[libosmium] 01/05: Imported Upstream version 2.10.0really2.9.0
Bas Couwenberg
sebastic at debian.org
Mon Nov 14 19:21:48 UTC 2016
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository libosmium.
commit 3f0c934b2b739412052c3d90f7624b9a316777e4
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Mon Nov 14 19:58:39 2016 +0100
Imported Upstream version 2.10.0really2.9.0
---
CHANGELOG.md | 58 +--
CMakeLists.txt | 6 +-
README.md | 4 +-
benchmarks/CMakeLists.txt | 3 -
benchmarks/download_data.sh | 10 +-
benchmarks/osmium_benchmark_count.cpp | 6 +-
benchmarks/osmium_benchmark_count_tag.cpp | 6 +-
benchmarks/osmium_benchmark_mercator.cpp | 43 --
benchmarks/run_benchmark_mercator.sh | 22 -
benchmarks/setup.sh | 16 +-
cmake/FindOsmium.cmake | 62 +--
examples/CMakeLists.txt | 8 +-
examples/README.md | 12 -
examples/osmium_area_test.cpp | 4 +-
examples/osmium_change_tags.cpp | 203 ----------
examples/osmium_convert.cpp | 8 +-
examples/osmium_create_pois.cpp | 96 -----
examples/osmium_dump_internal.cpp | 179 ---------
examples/osmium_filter_discussions.cpp | 2 +-
examples/osmium_index.cpp | 260 ++++++++++++
examples/osmium_index_lookup.cpp | 333 ----------------
examples/osmium_pub_names.cpp | 0
examples/osmium_road_length.cpp | 0
examples/osmium_serdump.cpp | 206 ++++++++++
include/osmium/area/assembler.hpp | 52 +--
include/osmium/area/detail/node_ref_segment.hpp | 4 +-
include/osmium/area/detail/segment_list.hpp | 2 +-
include/osmium/area/detail/vector.hpp | 20 +-
include/osmium/builder/attr.hpp | 64 ++-
include/osmium/builder/builder.hpp | 91 +++--
include/osmium/builder/osm_object_builder.hpp | 314 ++-------------
include/osmium/geom/factory.hpp | 2 +-
include/osmium/geom/geos.hpp | 16 +-
include/osmium/geom/relations.hpp | 10 +-
include/osmium/geom/tile.hpp | 20 +-
include/osmium/handler/disk_store.hpp | 5 +-
include/osmium/handler/node_locations_for_ways.hpp | 2 +-
include/osmium/handler/object_relations.hpp | 2 -
include/osmium/index/bool_vector.hpp | 41 +-
include/osmium/index/detail/vector_map.hpp | 6 +-
include/osmium/index/id_set.hpp | 431 --------------------
include/osmium/index/index.hpp | 12 +-
include/osmium/index/map.hpp | 27 +-
include/osmium/index/map/dummy.hpp | 2 +-
include/osmium/index/map/sparse_mem_map.hpp | 2 +-
include/osmium/index/map/sparse_mem_table.hpp | 4 +-
include/osmium/io/compression.hpp | 60 +--
include/osmium/io/detail/input_format.hpp | 23 +-
include/osmium/io/detail/o5m_input_format.hpp | 104 ++---
include/osmium/io/detail/opl_input_format.hpp | 8 +-
include/osmium/io/detail/opl_parser_functions.hpp | 80 ++--
include/osmium/io/detail/pbf_decoder.hpp | 170 ++------
include/osmium/io/detail/pbf_input_format.hpp | 10 +-
include/osmium/io/detail/queue_util.hpp | 13 +-
include/osmium/io/detail/xml_input_format.hpp | 94 ++---
include/osmium/io/file_format.hpp | 5 -
include/osmium/io/header.hpp | 79 +---
include/osmium/io/reader.hpp | 63 +--
include/osmium/memory/buffer.hpp | 82 ++--
include/osmium/memory/collection.hpp | 47 +--
include/osmium/memory/item.hpp | 4 +-
include/osmium/osm/area.hpp | 12 +-
include/osmium/osm/changeset.hpp | 18 +-
include/osmium/osm/crc.hpp | 42 +-
include/osmium/osm/entity_bits.hpp | 24 +-
include/osmium/osm/location.hpp | 52 +--
include/osmium/osm/node.hpp | 8 +-
include/osmium/osm/node_ref_list.hpp | 33 +-
include/osmium/osm/object.hpp | 8 -
include/osmium/osm/relation.hpp | 17 +-
include/osmium/osm/tag.hpp | 19 +-
include/osmium/osm/way.hpp | 6 +-
include/osmium/relations/collector.hpp | 58 +--
include/osmium/relations/detail/member_meta.hpp | 40 +-
include/osmium/thread/queue.hpp | 57 +--
include/osmium/util/progress_bar.hpp | 12 -
include/osmium/version.hpp | 4 +-
test/CMakeLists.txt | 52 +--
test/data-tests/testdata-xml.cpp | 2 +-
test/examples/CMakeLists.txt | 21 -
test/examples/t/pub_names/CMakeLists.txt | 7 -
test/examples/t/pub_names/pubs.osm | 7 -
test/examples/t/road_length/CMakeLists.txt | 8 -
test/examples/t/road_length/road.osm | 59 ---
test/include/catch.hpp | 50 +--
test/t/{osm => basic}/test_area.cpp | 0
test/t/{osm => basic}/test_box.cpp | 0
test/t/{osm => basic}/test_changeset.cpp | 67 ++--
test/t/{osm => basic}/test_crc.cpp | 0
test/t/basic/test_entity_bits.cpp | 32 ++
test/t/{osm => basic}/test_location.cpp | 119 +++---
test/t/{osm => basic}/test_node.cpp | 0
test/t/{osm => basic}/test_node_ref.cpp | 0
test/t/{osm => basic}/test_object_comparisons.cpp | 0
test/t/{osm => basic}/test_relation.cpp | 0
test/t/{osm => basic}/test_timestamp.cpp | 0
test/t/{osm => basic}/test_types_from_string.cpp | 0
test/t/{osm => basic}/test_way.cpp | 2 +-
test/t/{memory => buffer}/test_buffer_basics.cpp | 0
test/t/{memory => buffer}/test_buffer_node.cpp | 140 ++++---
test/t/{memory => buffer}/test_buffer_purge.cpp | 82 ++--
test/t/builder/test_object_builder.cpp | 444 ---------------------
test/t/geom/helper.hpp | 15 +
test/t/geom/test_crs.cpp | 10 +-
test/t/geom/test_exception.cpp | 8 +-
test/t/geom/test_factory_with_projection.cpp | 40 +-
test/t/geom/test_geojson.cpp | 193 +++++----
test/t/geom/test_geos.cpp | 56 ++-
test/t/geom/test_geos_wkb.cpp | 92 +++++
test/t/geom/test_ogr.cpp | 128 +++---
test/t/geom/test_ogr_wkb.cpp | 100 -----
test/t/geom/test_projection.cpp | 143 ++++---
test/t/geom/test_tile.cpp | 2 +
test/t/geom/test_wkb.cpp | 18 +-
test/t/geom/wnl_helper.hpp | 6 +-
test/t/index/test_id_set.cpp | 166 --------
test/t/index/test_id_to_location.cpp | 165 ++++----
test/t/io/test_compression_factory.cpp | 27 --
test/t/io/test_reader_with_mock_parser.cpp | 8 +-
test/t/osm/test_entity_bits.cpp | 62 ---
120 files changed, 2012 insertions(+), 4247 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 25327c8..0d132ef 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,53 +13,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
-## [2.10.0] - 2016-11-11
-
-### Added
-
-- The `Reader` can take an additional optional `read_meta` flag. If this is
- set to false the PBF input will ignore metadata on OSM objects (like version,
- timestamp, uid, ...) which speeds up file reading by 10 to 20%.
-- New `IdSet` virtual class with two implementations: `IdSetDense` and
- `IdSetSmall`. Used to efficiently store a set of Ids. This is often needed
- to track, for instance, which nodes are needed for ways, etc.
-- Added more examples and better documented existing examples.
-- Add a benchmark "mercator" converting all node locations in a file to
- WebMercator and creating geometries in WKB format.
-
-### Changed
-
-- Better queue handling makes I/O faster in some circumstances.
-- The `FindOsmium.cmake` CMake script can now check a current enough libosmium
- version is found.
-- Builders can now be constructed with a reference to parent builder.
-- Made builders more robust by adding asserts that will catch common usage
- problems.
-- Calling `OSMObjectBuilder::add_user()` is now optional, and the method was
- renamed to `set_user()`. (`add_user()` is marked as deprecated.)
-- Benchmarks now show compiler and compiler options used.
-- `Builder::add_item()` now takes a reference instead of pointer (old version
- of the function marked as deprecated).
-- GEOS support is deprecated. It does not work any more for GEOS 3.6 or newer.
- Reason is the changed interface in GEOS 3.6. If there is interest for the
- GEOS support, we can add support back in later (but probably using the
- GEOS C API which is more stable than the C++ API). Some tests using GEOS
- were rewritten to work without it.
-- The `BoolVector` has been deprecated in favour of the new `IdSet` classes.
-- Lots of code cleanups and improved API documentation in many places.
-- The relations collector can now tell you whether a relation member was in
- the input data. See the new `is_available()` and
- `get_availability_and_offset()` methods.
-- Updated embedded Catch unit test header to version 1.5.8.
-
-### Fixed
-
-- Parsing of coordinates starting with decimal dot and coordinates in
- scientific notation.
-- `~` operator for `entity_bits` doesn't set unused bits any more.
-- Progress bar can now be (temporarily) removed, to allow other output.
-
-
## [2.9.0] - 2016-09-15
### Added
@@ -157,7 +110,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- New functions for iterating over specific item types in buffers
(`osmium::memory::Buffer::select()`), over specific subitems
(`osmium::OSMObject::subitems()`), and for iterating over all rings of
- an area (`osmium::Areas::outer_rings()`, `inner_rings()`).
+ an area (`osmium::Areas::outer_rings(`), `inner_rings()`).
- Debug output optionally prints CRC32 when `add_crc32` file option is set.
### Changed
@@ -314,9 +267,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
one in Writer. Calling flush() on the OutputIterator isn't needed any
more.
- Reader now throws when trying to read after eof or an error.
-- I/O functions that used to throw `std::runtime_error` now throw
- `osmium::io_error` or derived.
-- Optional parameters on `osmium::io::Writer` now work in any order.
+- I/O functions that used to throw std::runtime_error now throw
+ osmium::io_error or derived.
+- Optional parameters on osmium::io::Writer now work in any order.
### Fixed
@@ -457,8 +410,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.10.0...HEAD
-[2.10.0]: https://github.com/osmcode/libosmium/compare/v2.9.0...v2.10.0
+[unreleased]: https://github.com/osmcode/libosmium/compare/v2.9.0...HEAD
[2.9.0]: https://github.com/osmcode/libosmium/compare/v2.8.0...v2.9.0
[2.8.0]: https://github.com/osmcode/libosmium/compare/v2.7.2...v2.8.0
[2.7.2]: https://github.com/osmcode/libosmium/compare/v2.7.1...v2.7.2
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 21cf98e..095137b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,7 @@ set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel;Dev;Cover
project(libosmium)
set(LIBOSMIUM_VERSION_MAJOR 2)
-set(LIBOSMIUM_VERSION_MINOR 10)
+set(LIBOSMIUM_VERSION_MINOR 9)
set(LIBOSMIUM_VERSION_PATCH 0)
set(LIBOSMIUM_VERSION
@@ -285,10 +285,6 @@ if(BUILD_DATA_TESTS)
add_subdirectory(test/data-tests)
endif()
-if(BUILD_EXAMPLES)
- add_subdirectory(test/examples)
-endif()
-
#-----------------------------------------------------------------------------
#
diff --git a/README.md b/README.md
index d526f13..68fc2f6 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,8 @@ http://osmcode.org/libosmium
A fast and flexible C++ library for working with OpenStreetMap data.
-[![Build Status](https://secure.travis-ci.org/osmcode/libosmium.svg)](https://travis-ci.org/osmcode/libosmium)
-[![Build status](https://ci.appveyor.com/api/projects/status/github/osmcode/libosmium?svg=true)](https://ci.appveyor.com/project/Mapbox/libosmium)
+[![Build Status](https://secure.travis-ci.org/osmcode/libosmium.png)](https://travis-ci.org/osmcode/libosmium)
+[![Build status](https://ci.appveyor.com/api/projects/status/mkbg6e6stdgq7c1b?svg=true)](https://ci.appveyor.com/project/Mapbox/libosmium)
Libosmium is developed on Linux, but also works on OSX and Windows (with some
limitations).
diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt
index 4b76fcb..e46c833 100644
--- a/benchmarks/CMakeLists.txt
+++ b/benchmarks/CMakeLists.txt
@@ -12,7 +12,6 @@ set(BENCHMARKS
count
count_tag
index_map
- mercator
static_vs_dynamic_index
write_pbf
CACHE STRING "Benchmark programs"
@@ -38,8 +37,6 @@ foreach(benchmark ${BENCHMARKS})
@ONLY)
endforeach()
-string(TOUPPER "${CMAKE_BUILD_TYPE}" _cmake_build_type)
-set(_cxx_flags "${CMAKE_CXX_FLAGS_${_cmake_build_type}}")
foreach(file setup run_benchmarks)
configure_file(${file}.sh ${CMAKE_CURRENT_BINARY_DIR}/${file}.sh @ONLY)
endforeach()
diff --git a/benchmarks/download_data.sh b/benchmarks/download_data.sh
index be6adb9..8a6a8ff 100755
--- a/benchmarks/download_data.sh
+++ b/benchmarks/download_data.sh
@@ -4,9 +4,9 @@
#
cd $DATA_DIR
-curl --location --output 1_liechtenstein.osm.pbf http://download.geofabrik.de/europe/liechtenstein-latest.osm.pbf # about 2 MB
-curl --location --output 2_bremen.osm.pbf http://download.geofabrik.de/europe/germany/bremen-latest.osm.pbf # about 16 MB
-curl --location --output 3_sachsen.osm.pbf http://download.geofabrik.de/europe/germany/sachsen-latest.osm.pbf # about 160 MB
-curl --location --output 4_germany.osm.pbf http://download.geofabrik.de/europe/germany-latest.osm.pbf # about 3 GB
-curl --location --output 5_planet.osm.pbf http://planet.osm.org/pbf/planet-latest.osm.pbf # about 35 GB
+curl --location --output 1_liechtenstein.osm.pbf http://download.geofabrik.de/europe/liechtenstein-latest.osm.pbf # about 1 MB
+curl --location --output 2_bremen.osm.pbf http://download.geofabrik.de/europe/germany/bremen-latest.osm.pbf # about 13 MB
+curl --location --output 3_sachsen.osm.pbf http://download.geofabrik.de/europe/germany/sachsen-latest.osm.pbf # about 120 MB
+curl --location --output 4_germany.osm.pbf http://download.geofabrik.de/europe/germany-latest.osm.pbf # about 2 GB
+curl --location --output 5_planet.osm.pbf http://planet.osm.org/pbf/planet-latest.osm.pbf # about 26 GB
diff --git a/benchmarks/osmium_benchmark_count.cpp b/benchmarks/osmium_benchmark_count.cpp
index 41f9aa0..1a16275 100644
--- a/benchmarks/osmium_benchmark_count.cpp
+++ b/benchmarks/osmium_benchmark_count.cpp
@@ -19,15 +19,15 @@ struct CountHandler : public osmium::handler::Handler {
uint64_t ways = 0;
uint64_t relations = 0;
- void node(const osmium::Node&) {
+ void node(osmium::Node&) {
++nodes;
}
- void way(const osmium::Way&) {
+ void way(osmium::Way&) {
++ways;
}
- void relation(const osmium::Relation&) {
+ void relation(osmium::Relation&) {
++relations;
}
diff --git a/benchmarks/osmium_benchmark_count_tag.cpp b/benchmarks/osmium_benchmark_count_tag.cpp
index 5b82a7c..6062ecc 100644
--- a/benchmarks/osmium_benchmark_count_tag.cpp
+++ b/benchmarks/osmium_benchmark_count_tag.cpp
@@ -18,7 +18,7 @@ struct CountHandler : public osmium::handler::Handler {
uint64_t counter = 0;
uint64_t all = 0;
- void node(const osmium::Node& node) {
+ void node(osmium::Node& node) {
++all;
const char* amenity = node.tags().get_value_by_key("amenity");
if (amenity && !strcmp(amenity, "post_box")) {
@@ -26,11 +26,11 @@ struct CountHandler : public osmium::handler::Handler {
}
}
- void way(const osmium::Way&) {
+ void way(osmium::Way&) {
++all;
}
- void relation(const osmium::Relation&) {
+ void relation(osmium::Relation&) {
++all;
}
diff --git a/benchmarks/osmium_benchmark_mercator.cpp b/benchmarks/osmium_benchmark_mercator.cpp
deleted file mode 100644
index 091e5c0..0000000
--- a/benchmarks/osmium_benchmark_mercator.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-
- The code in this file is released into the Public Domain.
-
-*/
-
-#include <cstdint>
-#include <cstdlib>
-#include <iostream>
-#include <string>
-
-#include <osmium/io/any_input.hpp>
-#include <osmium/handler.hpp>
-#include <osmium/visitor.hpp>
-#include <osmium/geom/wkb.hpp>
-#include <osmium/geom/mercator_projection.hpp>
-
-struct GeomHandler : public osmium::handler::Handler {
-
- osmium::geom::WKBFactory<osmium::geom::MercatorProjection> factory;
-
- void node(const osmium::Node& node) {
- const std::string geom = factory.create_point(node);
- }
-
-};
-
-
-int main(int argc, char* argv[]) {
- if (argc != 2) {
- std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
- std::exit(1);
- }
-
- const std::string input_filename{argv[1]};
-
- osmium::io::Reader reader{input_filename};
-
- GeomHandler handler;
- osmium::apply(reader, handler);
- reader.close();
-}
-
diff --git a/benchmarks/run_benchmark_mercator.sh b/benchmarks/run_benchmark_mercator.sh
deleted file mode 100755
index a520727..0000000
--- a/benchmarks/run_benchmark_mercator.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-#
-# run_benchmark_mercator.sh
-#
-
-set -e
-
-BENCHMARK_NAME=mercator
-
-. @CMAKE_BINARY_DIR@/benchmarks/setup.sh
-
-CMD=$OB_DIR/osmium_benchmark_$BENCHMARK_NAME
-
-echo "# file size num mem time cpu_kernel cpu_user cpu_percent cmd options"
-for data in $OB_DATA_FILES; do
- filename=`basename $data`
- filesize=`stat --format="%s" --dereference $data`
- for n in $OB_SEQ; do
- $OB_TIME_CMD -f "$filename $filesize $n $OB_TIME_FORMAT" $CMD $data 2>&1 >/dev/null | sed -e "s%$DATA_DIR/%%" | sed -e "s%$OB_DIR/%%"
- done
-done
-
diff --git a/benchmarks/setup.sh b/benchmarks/setup.sh
index f8901c2..9733bfe 100755
--- a/benchmarks/setup.sh
+++ b/benchmarks/setup.sh
@@ -9,10 +9,6 @@ if [ -z $DATA_DIR ]; then
fi
OB_DIR=@CMAKE_BINARY_DIR@/benchmarks
-OB_BUILD_TYPE=@CMAKE_BUILD_TYPE@
-OB_COMPILER=@CMAKE_CXX_COMPILER@
-OB_COMPILER_VERSION=`$OB_COMPILER --version | head -1`
-OB_CXXFLAGS="@_cxx_flags@"
OB_RUNS=3
OB_SEQ=`seq -s' ' 1 $OB_RUNS`
@@ -24,17 +20,11 @@ OB_DATA_FILES=`find -L $DATA_DIR -mindepth 1 -maxdepth 1 -type f | sort`
echo "BENCHMARK: $BENCHMARK_NAME"
echo "---------------------"
-echo "BUILD:"
-echo "build type\t: $OB_BUILD_TYPE"
-echo "compiler\t: $OB_COMPILER"
-echo "CXX version\t: $OB_COMPILER_VERSION"
-echo "CXX flags\t: $OB_CXXFLAGS"
-echo "---------------------"
echo "CPU:"
grep '^model name' /proc/cpuinfo | tail -1
-grep '^cpu MHz' /proc/cpuinfo | tail -1
-grep '^cpu cores' /proc/cpuinfo | tail -1
-grep '^siblings' /proc/cpuinfo | tail -1
+grep '^cpu MHz' /proc/cpuinfo | tail -1
+grep '^cpu cores' /proc/cpuinfo | tail -1
+grep '^siblings' /proc/cpuinfo | tail -1
echo "---------------------"
echo "MEMORY:"
diff --git a/cmake/FindOsmium.cmake b/cmake/FindOsmium.cmake
index 2224e18..fba8ffb 100644
--- a/cmake/FindOsmium.cmake
+++ b/cmake/FindOsmium.cmake
@@ -2,8 +2,8 @@
#
# FindOsmium.cmake
#
-# Find the Libosmium headers and, optionally, several components needed
-# for different Libosmium functions.
+# Find the Libosmium headers and, optionally, several components needed for
+# different Libosmium functions.
#
#----------------------------------------------------------------------
#
@@ -18,12 +18,9 @@
#
# Then add the following in your CMakeLists.txt:
#
-# find_package(Osmium [version] REQUIRED COMPONENTS <XXX>)
+# find_package(Osmium REQUIRED COMPONENTS <XXX>)
# include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
#
-# The version number is optional. If it is not set, any version of
-# libosmium will do.
-#
# For the <XXX> substitute a space separated list of one or more of the
# following components:
#
@@ -54,9 +51,10 @@
#
#----------------------------------------------------------------------
-# This is the list of directories where we look for osmium and protozero
-# includes.
-set(_osmium_include_path
+# Look for the header file.
+find_path(OSMIUM_INCLUDE_DIR osmium/osm.hpp
+ PATH_SUFFIXES include
+ PATHS
../libosmium
~/Library/Frameworks
/Library/Frameworks
@@ -64,22 +62,6 @@ set(_osmium_include_path
/opt
)
-# Look for the header file.
-find_path(OSMIUM_INCLUDE_DIR osmium/version.hpp
- PATH_SUFFIXES include
- PATHS ${_osmium_include_path}
-)
-
-# Check libosmium version number
-if(Osmium_FIND_VERSION)
- file(STRINGS "${OSMIUM_INCLUDE_DIR}/osmium/version.hpp" _libosmium_version_define REGEX "#define LIBOSMIUM_VERSION_STRING")
- if("${_libosmium_version_define}" MATCHES "#define LIBOSMIUM_VERSION_STRING \"([0-9.]+)\"")
- set(_libosmium_version "${CMAKE_MATCH_1}")
- else()
- set(_libosmium_version "unknown")
- endif()
-endif()
-
set(OSMIUM_INCLUDE_DIRS "${OSMIUM_INCLUDE_DIR}")
#----------------------------------------------------------------------
@@ -113,31 +95,17 @@ if(Osmium_USE_PBF)
find_package(ZLIB)
find_package(Threads)
- message(STATUS "Looking for protozero")
- find_path(PROTOZERO_INCLUDE_DIR protozero/version.hpp
- PATH_SUFFIXES include
- PATHS ${_osmium_include_path}
- ${OSMIUM_INCLUDE_DIR}
- )
- if(PROTOZERO_INCLUDE_DIR)
- message(STATUS "Looking for protozero - found")
- else()
- message(STATUS "Looking for protozero - not found")
- endif()
-
- list(APPEND OSMIUM_EXTRA_FIND_VARS ZLIB_FOUND Threads_FOUND PROTOZERO_INCLUDE_DIR)
- if(ZLIB_FOUND AND Threads_FOUND AND PROTOZERO_INCLUDE_DIR)
+ list(APPEND OSMIUM_EXTRA_FIND_VARS ZLIB_FOUND Threads_FOUND)
+ if(ZLIB_FOUND AND Threads_FOUND)
list(APPEND OSMIUM_PBF_LIBRARIES
${ZLIB_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)
if(WIN32)
- # This is needed for the ntohl() function
list(APPEND OSMIUM_PBF_LIBRARIES ws2_32)
endif()
list(APPEND OSMIUM_INCLUDE_DIRS
${ZLIB_INCLUDE_DIR}
- ${PROTOZERO_INCLUDE_DIR}
)
else()
message(WARNING "Osmium: Can not find some libraries for PBF input/output, please install them or configure the paths.")
@@ -235,7 +203,7 @@ if(Osmium_USE_SPARSEHASH)
if(SPARSEHASH_INCLUDE_DIR)
# Find size of sparsetable::size_type. This does not work on older
# CMake versions because they can do this check only in C, not in C++.
- if(NOT CMAKE_VERSION VERSION_LESS 3.0)
+ if (NOT CMAKE_VERSION VERSION_LESS 3.0)
include(CheckTypeSize)
set(CMAKE_REQUIRED_INCLUDES ${SPARSEHASH_INCLUDE_DIR})
set(CMAKE_EXTRA_INCLUDE_FILES "google/sparsetable")
@@ -285,15 +253,13 @@ endif()
# Check that all required libraries are available
#
#----------------------------------------------------------------------
-if(OSMIUM_EXTRA_FIND_VARS)
+if (OSMIUM_EXTRA_FIND_VARS)
list(REMOVE_DUPLICATES OSMIUM_EXTRA_FIND_VARS)
endif()
-# Handle the QUIETLY and REQUIRED arguments and the optional version check
-# and set OSMIUM_FOUND to TRUE if all listed variables are TRUE.
+# Handle the QUIETLY and REQUIRED arguments and set OSMIUM_FOUND to TRUE if
+# all listed variables are TRUE.
include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Osmium
- REQUIRED_VARS OSMIUM_INCLUDE_DIR ${OSMIUM_EXTRA_FIND_VARS}
- VERSION_VAR _libosmium_version)
+find_package_handle_standard_args(Osmium REQUIRED_VARS OSMIUM_INCLUDE_DIR ${OSMIUM_EXTRA_FIND_VARS})
unset(OSMIUM_EXTRA_FIND_VARS)
#----------------------------------------------------------------------
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index ac07896..b47cfdc 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -10,20 +10,18 @@ message(STATUS "Configuring examples")
set(EXAMPLES
area_test
- change_tags
convert
count
- create_pois
debug
- dump_internal
filter_discussions
- index_lookup
+ index
location_cache_create
location_cache_use
pub_names
read
read_with_progress
road_length
+ serdump
tiles
CACHE STRING "Example programs"
)
@@ -34,7 +32,7 @@ set(EXAMPLES
# Examples depending on wingetopt
#
#-----------------------------------------------------------------------------
-set(GETOPT_EXAMPLES area_test convert index_lookup)
+set(GETOPT_EXAMPLES area_test convert index serdump)
if(NOT GETOPT_MISSING)
foreach(example ${GETOPT_EXAMPLES})
list(APPEND EXAMPLE_LIBS_${example} ${GETOPT_LIBRARY})
diff --git a/examples/README.md b/examples/README.md
index 55bd406..e291032 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -18,24 +18,12 @@ them.
## Still reasonably simple examples
-* `osmium_read_with_progress`
* `osmium_filter_discussions`
* `osmium_convert`
-* `osmium_pub_names`
-* `osmium_road_length`
## More advanced examples
* `osmium_area_test`
-* `osmium_create_pois`
-
-## Even more advanced examples
-
-* `osmium_change_tags`
-* `osmium_location_cache_create`
-* `osmium_location_cache_use`
-* `osmium_dump_internal`
-* `osmium_index_lookup`
## License
diff --git a/examples/osmium_area_test.cpp b/examples/osmium_area_test.cpp
index 0c849a7..0303374 100644
--- a/examples/osmium_area_test.cpp
+++ b/examples/osmium_area_test.cpp
@@ -106,7 +106,7 @@ int main(int argc, char* argv[]) {
// Read options from command line.
while (true) {
- const int c = getopt_long(argc, argv, "hwo", long_options, 0);
+ int c = getopt_long(argc, argv, "hwo", long_options, 0);
if (c == -1) {
break;
}
@@ -126,7 +126,7 @@ int main(int argc, char* argv[]) {
}
}
- const int remaining_args = argc - optind;
+ int remaining_args = argc - optind;
if (remaining_args != 1) {
std::cerr << "Usage: " << argv[0] << " [OPTIONS] OSMFILE\n";
std::exit(1);
diff --git a/examples/osmium_change_tags.cpp b/examples/osmium_change_tags.cpp
deleted file mode 100644
index a7c1904..0000000
--- a/examples/osmium_change_tags.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
-
- EXAMPLE osmium_change_tags
-
- An example how tags in OSM files can be removed or changed. Removes
- "created_by" tags and changes tag "landuse=forest" into "natural_wood".
-
- DEMONSTRATES USE OF:
- * file input and output
- * Osmium buffers
- * your own handler
- * access to tags
- * using builders to write data
-
- SIMPLER EXAMPLES you might want to understand first:
- * osmium_read
- * osmium_count
- * osmium_pub_names
-
- LICENSE
- The code in this example file is released into the Public Domain.
-
-*/
-
-#include <cstdlib> // for std::exit
-#include <cstring> // for std::strcmp
-#include <exception> // for std::exception
-#include <iostream> // for std::cout, std::cerr
-#include <string> // for std::string
-#include <utility> // for std::move
-
-// Allow any format of input files (XML, PBF, ...)
-#include <osmium/io/any_input.hpp>
-
-// Allow any format of output files (XML, PBF, ...)
-#include <osmium/io/any_output.hpp>
-
-// We want to use the builder interface
-#include <osmium/builder/osm_object_builder.hpp>
-
-// We want to use the handler interface
-#include <osmium/handler.hpp>
-
-// For osmium::apply()
-#include <osmium/visitor.hpp>
-
-// The functions in this class will be called for each object in the input
-// and will write a (changed) copy of those objects to the given buffer.
-class RewriteHandler : public osmium::handler::Handler {
-
- osmium::memory::Buffer& m_buffer;
-
- // Copy attributes common to all OSM objects (nodes, ways, and relations).
- template <typename T>
- void copy_attributes(T& builder, const osmium::OSMObject& object) {
- // The setter functions on the builder object all return the same
- // builder object so they can be chained.
- builder.set_id(object.id())
- .set_version(object.version())
- .set_changeset(object.changeset())
- .set_timestamp(object.timestamp())
- .set_uid(object.uid())
- .set_user(object.user());
- }
-
- // Copy all tags with two changes:
- // * Do not copy "created_by" tags
- // * Change "landuse=forest" into "natural=wood"
- void copy_tags(osmium::builder::Builder& parent, const osmium::TagList& tags) {
-
- // The TagListBuilder is used to create a list of tags. The parameter
- // to create it is a reference to the builder of the object that
- // should have those tags.
- osmium::builder::TagListBuilder builder{parent};
-
- // Iterate over all tags and build new tags using the new builder
- // based on the old ones.
- for (const auto& tag : tags) {
- if (std::strcmp(tag.key(), "created_by")) {
- if (!std::strcmp(tag.key(), "landuse") && !std::strcmp(tag.value(), "forest")) {
- // add_tag() can be called with key and value C strings
- builder.add_tag("natural", "wood");
- } else {
- // add_tag() can also be called with an osmium::Tag
- builder.add_tag(tag);
- }
- }
- }
- }
-
-public:
-
- // Constructor. New data will be added to the given buffer.
- RewriteHandler(osmium::memory::Buffer& buffer) :
- m_buffer(buffer) {
- }
-
- // The node handler is called for each node in the input data.
- void node(const osmium::Node& node) {
- // Open a new scope, because the NodeBuilder we are creating has to
- // be destructed, before we can call commit() below.
- {
- // To create a node, we need a NodeBuilder object. It will create
- // the node in the given buffer.
- osmium::builder::NodeBuilder builder{m_buffer};
-
- // Copy common object attributes over to the new node.
- copy_attributes(builder, node);
-
- // Copy the location over to the new node.
- builder.set_location(node.location());
-
- // Copy (changed) tags.
- copy_tags(builder, node.tags());
- }
-
- // Once the object is written to the buffer completely, we have to call
- // commit().
- m_buffer.commit();
- }
-
- // The way handler is called for each node in the input data.
- void way(const osmium::Way& way) {
- {
- osmium::builder::WayBuilder builder{m_buffer};
- copy_attributes(builder, way);
- copy_tags(builder, way.tags());
-
- // Copy the node list over to the new way.
- builder.add_item(way.nodes());
- }
- m_buffer.commit();
- }
-
- // The relation handler is called for each node in the input data.
- void relation(const osmium::Relation& relation) {
- {
- osmium::builder::RelationBuilder builder{m_buffer};
- copy_attributes(builder, relation);
- copy_tags(builder, relation.tags());
-
- // Copy the relation member list over to the new way.
- builder.add_item(relation.members());
- }
- m_buffer.commit();
- }
-
-}; // class RewriteHandler
-
-int main(int argc, char* argv[]) {
- if (argc != 3) {
- std::cerr << "Usage: " << argv[0] << " INFILE OUTFILE\n";
- std::exit(1);
- }
-
- // Get input and output file names from command line.
- std::string input_file_name{argv[1]};
- std::string output_file_name{argv[2]};
-
- try {
- // Initialize Reader
- osmium::io::Reader reader{input_file_name};
-
- // Get header from input file and change the "generator" setting to
- // ourselves.
- osmium::io::Header header = reader.header();
- header.set("generator", "osmium_change_tags");
-
- // Initialize Writer using the header from above and tell it that it
- // is allowed to overwrite a possibly existing file.
- osmium::io::Writer writer{output_file_name, header, osmium::io::overwrite::allow};
-
- // Read in buffers with OSM objects until there are no more.
- while (osmium::memory::Buffer input_buffer = reader.read()) {
- // Create an empty buffer with the same size as the input buffer.
- // We'll copy the changed data into output buffer, the changes
- // are small, so the output buffer needs to be about the same size.
- // In case it has to be bigger, we allow it to grow automatically
- // by adding the auto_grow::yes parameter.
- osmium::memory::Buffer output_buffer{input_buffer.committed(), osmium::memory::Buffer::auto_grow::yes};
-
- // Construct a handler as defined above and feed the input buffer
- // to it.
- RewriteHandler handler{output_buffer};
- osmium::apply(input_buffer, handler);
-
- // Write out the contents of the output buffer.
- writer(std::move(output_buffer));
- }
-
- // Explicitly close the writer and reader. Will throw an exception if
- // there is a problem. If you wait for the destructor to close the writer
- // and reader, you will not notice the problem, because destructors must
- // not throw.
- writer.close();
- reader.close();
- } catch (const std::exception& e) {
- // All exceptions used by the Osmium library derive from std::exception.
- std::cerr << e.what() << "\n";
- std::exit(1);
- }
-}
-
diff --git a/examples/osmium_convert.cpp b/examples/osmium_convert.cpp
index 0ced82c..48a0823 100644
--- a/examples/osmium_convert.cpp
+++ b/examples/osmium_convert.cpp
@@ -67,7 +67,7 @@ int main(int argc, char* argv[]) {
// Read options from command line.
while (true) {
- const int c = getopt_long(argc, argv, "dhf:t:", long_options, 0);
+ int c = getopt_long(argc, argv, "dhf:t:", long_options, 0);
if (c == -1) {
break;
}
@@ -87,7 +87,7 @@ int main(int argc, char* argv[]) {
}
}
- const int remaining_args = argc - optind;
+ int remaining_args = argc - optind;
if (remaining_args > 2) {
std::cerr << "Usage: " << argv[0] << " [OPTIONS] [INFILE [OUTFILE]]\n";
std::exit(1);
@@ -124,13 +124,13 @@ int main(int argc, char* argv[]) {
osmium::io::Reader reader{input_file};
// Get header from input file and change the "generator" setting to
- // ourselves.
+ // outselves.
osmium::io::Header header = reader.header();
header.set("generator", "osmium_convert");
// Initialize Writer using the header from above and tell it that it
// is allowed to overwrite a possibly existing file.
- osmium::io::Writer writer{output_file, header, osmium::io::overwrite::allow};
+ osmium::io::Writer writer(output_file, header, osmium::io::overwrite::allow);
// Copy the contents from the input to the output file one buffer at
// a time. This is much easier and faster than copying each object
diff --git a/examples/osmium_create_pois.cpp b/examples/osmium_create_pois.cpp
deleted file mode 100644
index ff79cbb..0000000
--- a/examples/osmium_create_pois.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-
- EXAMPLE osmium_create_pois
-
- Showing how to create nodes for points of interest out of thin air.
-
- DEMONSTRATES USE OF:
- * file output
- * Osmium buffers
- * using builders to write data
-
- SIMPLER EXAMPLES you might want to understand first:
- * osmium_read
- * osmium_count
- * osmium_pub_names
-
- LICENSE
- The code in this example file is released into the Public Domain.
-
-*/
-
-#include <cstdlib> // for std::exit
-#include <cstring> // for std::strcmp
-#include <ctime> // for std::time
-#include <exception> // for std::exception
-#include <iostream> // for std::cout, std::cerr
-#include <string> // for std::string
-#include <utility> // for std::move
-
-// Allow any format of output files (XML, PBF, ...)
-#include <osmium/io/any_output.hpp>
-
-// We want to use the builder interface
-#include <osmium/builder/osm_object_builder.hpp>
-#include <osmium/builder/attr.hpp>
-
-// Declare this to use the functions starting with the underscore (_) below.
-using namespace osmium::builder::attr;
-
-int main(int argc, char* argv[]) {
- if (argc != 2) {
- std::cerr << "Usage: " << argv[0] << " OUTFILE\n";
- std::exit(1);
- }
-
- // Get output file name from command line.
- std::string output_file_name{argv[1]};
-
- try {
- // Create a buffer where all objects will live. Use a sensible initial
- // buffer size and set the buffer to automatically grow if needed.
- const size_t initial_buffer_size = 10000;
- osmium::memory::Buffer buffer{initial_buffer_size, osmium::memory::Buffer::auto_grow::yes};
-
- // Add nodes to the buffer. This is, of course, only an example.
- // You can set any of the attributes and more tags, etc. Ways and
- // relations can be added in a similar way.
- osmium::builder::add_node(buffer,
- _id(-1),
- _version(1),
- _timestamp(std::time(nullptr)),
- _location(osmium::Location{1.23, 3.45}),
- _tag("amenity", "post_box")
- );
-
- osmium::builder::add_node(buffer,
- _id(-2),
- _version(1),
- _timestamp(std::time(nullptr)),
- _location(1.24, 3.46),
- _tags({{"amenity", "restaurant"},
- {"name", "Chez OSM"}})
- );
-
- // Create header and set generator.
- osmium::io::Header header;
- header.set("generator", "osmium_create_pois");
-
- // Initialize Writer using the header from above and tell it that it
- // is allowed to overwrite a possibly existing file.
- osmium::io::Writer writer{output_file_name, header, osmium::io::overwrite::allow};
-
- // Write out the contents of the output buffer.
- writer(std::move(buffer));
-
- // Explicitly close the writer. Will throw an exception if there is
- // a problem. If you wait for the destructor to close the writer, you
- // will not notice the problem, because destructors must not throw.
- writer.close();
- } catch (const std::exception& e) {
- // All exceptions used by the Osmium library derive from std::exception.
- std::cerr << e.what() << "\n";
- std::exit(1);
- }
-}
-
diff --git a/examples/osmium_dump_internal.cpp b/examples/osmium_dump_internal.cpp
deleted file mode 100644
index dbc50db..0000000
--- a/examples/osmium_dump_internal.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
-
- EXAMPLE osmium_dump_internal
-
- Reads an OSM file and dumps the internal datastructure to disk including
- indexes to find objects and object relations.
-
- Note that this example programm will only work with small and medium sized
- OSM file, not with the planet.
-
- You can use the osmium_index example program to inspect the indexes.
-
- DEMONSTRATES USE OF:
- * file input
- * indexes and maps
- * use of the DiskStore handler
- * use of the ObjectRelations handler
-
- SIMPLER EXAMPLES you might want to understand first:
- * osmium_read
- * osmium_count
- * osmium_road_length
- * osmium_location_cache_create
- * osmium_location_cache_use
-
- LICENSE
- The code in this example file is released into the Public Domain.
-
-*/
-
-#include <cerrno> // for errno
-#include <cstring> // for std::strerror
-#include <cstdlib> // for std::exit
-#include <iostream> // for std::cout, std::cerr
-#include <string> // for std::string
-#include <sys/stat.h> // for open
-#include <sys/types.h> // for open
-
-#ifdef _MSC_VER
-# include <direct.h>
-#endif
-
-// Allow any format of input files (XML, PBF, ...)
-#include <osmium/io/any_input.hpp>
-
-// The DiskStore handler
-#include <osmium/handler/disk_store.hpp>
-
-// The ObjectRelations handler
-#include <osmium/handler/object_relations.hpp>
-
-// The indexes
-#include <osmium/index/map/sparse_mem_array.hpp>
-#include <osmium/index/multimap/sparse_mem_array.hpp>
-
-using offset_index_type = osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, size_t>;
-using map_type = osmium::index::multimap::SparseMemArray<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type>;
-
-/**
- * Small class wrapping index files, basically making sure errors are handled
- * and the files are closed on destruction.
- */
-class IndexFile {
-
- int m_fd;
-
-public:
-
- IndexFile(const std::string& filename) :
- m_fd(::open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666)) {
- if (m_fd < 0) {
- std::cerr << "Can't open index file '" << filename << "': " << std::strerror(errno) << "\n";
- std::exit(2);
- }
- }
-
- ~IndexFile() {
- if (m_fd >= 0) {
- close(m_fd);
- }
- }
-
- int fd() const noexcept {
- return m_fd;
- }
-
-}; // class IndexFile
-
-int main(int argc, char* argv[]) {
- if (argc != 3) {
- std::cerr << "Usage: " << argv[0] << " OSMFILE DIR\n";
- std::exit(2);
- }
-
- const std::string input_file_name{argv[1]};
- const std::string output_dir{argv[2]};
-
- // Create output directory. Ignore the error if it already exists.
-#ifndef _WIN32
- const int result = ::mkdir(output_dir.c_str(), 0777);
-#else
- const int result = mkdir(output_dir.c_str());
-#endif
- if (result == -1 && errno != EEXIST) {
- std::cerr << "Problem creating directory '" << output_dir << "': " << std::strerror(errno) << "\n";
- std::exit(2);
- }
-
- // Create the output file which will contain our serialized OSM data
- const std::string data_file{output_dir + "/data.osm.ser"};
- const int data_fd = ::open(data_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (data_fd < 0) {
- std::cerr << "Can't open data file '" << data_file << "': " << std::strerror(errno) << "\n";
- std::exit(2);
- }
-
- // These indexes store the offset in the data file where each node, way,
- // or relation is stored.
- offset_index_type node_index;
- offset_index_type way_index;
- offset_index_type relation_index;
-
- // This handler will dump the internal data to disk using the given file
- // descriptor while updating the indexes.
- osmium::handler::DiskStore disk_store_handler{data_fd, node_index, way_index, relation_index};
-
- // These indexes store the mapping from node id to the ids of the ways
- // containing this node, and from node/way/relation ids to the ids of the
- // relations containing those objects.
- map_type map_node2way;
- map_type map_node2relation;
- map_type map_way2relation;
- map_type map_relation2relation;
-
- // This handler will update the map indexes.
- osmium::handler::ObjectRelations object_relations_handler{map_node2way, map_node2relation, map_way2relation, map_relation2relation};
-
- // Read OSM data buffer by buffer.
- osmium::io::Reader reader{input_file_name};
-
- while (osmium::memory::Buffer buffer = reader.read()) {
- // Write buffer to disk and update indexes.
- disk_store_handler(buffer);
-
- // Update object relation index maps.
- osmium::apply(buffer, object_relations_handler);
- }
-
- reader.close();
-
- // Write out node, way, and relation offset indexes to disk.
- IndexFile nodes_idx{output_dir + "/nodes.idx"};
- node_index.dump_as_list(nodes_idx.fd());
-
- IndexFile ways_idx{output_dir + "/ways.idx"};
- way_index.dump_as_list(ways_idx.fd());
-
- IndexFile relations_idx{output_dir + "/relations.idx"};
- relation_index.dump_as_list(relations_idx.fd());
-
- // Sort the maps (so later binary search will work on them) and write
- // them to disk.
- map_node2way.sort();
- IndexFile node2way_idx{output_dir + "/node2way.map"};
- map_node2way.dump_as_list(node2way_idx.fd());
-
- map_node2relation.sort();
- IndexFile node2relation_idx{output_dir + "/node2rel.map"};
- map_node2relation.dump_as_list(node2relation_idx.fd());
-
- map_way2relation.sort();
- IndexFile way2relation_idx{output_dir + "/way2rel.map"};
- map_way2relation.dump_as_list(way2relation_idx.fd());
-
- map_relation2relation.sort();
- IndexFile relation2relation_idx{output_dir + "/rel2rel.map"};
- map_relation2relation.dump_as_list(relation2relation_idx.fd());
-}
-
diff --git a/examples/osmium_filter_discussions.cpp b/examples/osmium_filter_discussions.cpp
index c2a94e5..6334981 100644
--- a/examples/osmium_filter_discussions.cpp
+++ b/examples/osmium_filter_discussions.cpp
@@ -67,7 +67,7 @@ int main(int argc, char* argv[]) {
// file for the output file. This will copy over some header information.
// The last parameter will tell the writer that it is allowed to overwrite
// an existing file. Without it, it will refuse to do so.
- osmium::io::Writer writer{output_file, header, osmium::io::overwrite::allow};
+ osmium::io::Writer writer(output_file, header, osmium::io::overwrite::allow);
// Create range of input iterators that will iterator over all changesets
// delivered from input file through the "reader".
diff --git a/examples/osmium_index.cpp b/examples/osmium_index.cpp
new file mode 100644
index 0000000..478b6c6
--- /dev/null
+++ b/examples/osmium_index.cpp
@@ -0,0 +1,260 @@
+/*
+
+ Example program to look at Osmium indexes on disk.
+
+ The code in this example file is released into the Public Domain.
+
+*/
+
+#include <fcntl.h>
+#include <iomanip>
+#include <iostream>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <getopt.h>
+
+#include <osmium/index/map/dense_file_array.hpp>
+#include <osmium/index/map/sparse_file_array.hpp>
+#include <osmium/osm/location.hpp>
+#include <osmium/osm/types.hpp>
+
+template <typename TKey, typename TValue>
+class IndexSearch {
+
+ typedef typename osmium::index::map::DenseFileArray<TKey, TValue> dense_index_type;
+ typedef typename osmium::index::map::SparseFileArray<TKey, TValue> sparse_index_type;
+
+ int m_fd;
+ bool m_dense_format;
+
+ void dump_dense() {
+ dense_index_type index(m_fd);
+
+ for (std::size_t i = 0; i < index.size(); ++i) {
+ if (index.get(i) != TValue()) {
+ std::cout << i << " " << index.get(i) << "\n";
+ }
+ }
+ }
+
+ void dump_sparse() {
+ sparse_index_type index(m_fd);
+
+ for (auto& element : index) {
+ std::cout << element.first << " " << element.second << "\n";
+ }
+ }
+
+ bool search_dense(TKey key) {
+ dense_index_type index(m_fd);
+
+ try {
+ TValue value = index.get(key);
+ std::cout << key << " " << value << "\n";
+ } catch (...) {
+ std::cout << key << " not found\n";
+ return false;
+ }
+
+ return true;
+ }
+
+ bool search_sparse(TKey key) {
+ typedef typename sparse_index_type::element_type element_type;
+ sparse_index_type index(m_fd);
+
+ element_type elem {key, TValue()};
+ auto positions = std::equal_range(index.begin(), index.end(), elem, [](const element_type& lhs, const element_type& rhs) {
+ return lhs.first < rhs.first;
+ });
+ if (positions.first == positions.second) {
+ std::cout << key << " not found\n";
+ return false;
+ }
+
+ for (auto& it = positions.first; it != positions.second; ++it) {
+ std::cout << it->first << " " << it->second << "\n";
+ }
+
+ return true;
+ }
+
+public:
+
+ IndexSearch(int fd, bool dense_format) :
+ m_fd(fd),
+ m_dense_format(dense_format) {
+ }
+
+ void dump() {
+ if (m_dense_format) {
+ dump_dense();
+ } else {
+ dump_sparse();
+ }
+ }
+
+ bool search(TKey key) {
+ if (m_dense_format) {
+ return search_dense(key);
+ } else {
+ return search_sparse(key);
+ }
+ }
+
+ bool search(const std::vector<TKey>& keys) {
+ bool found_all = true;
+
+ for (const auto key : keys) {
+ if (!search(key)) {
+ found_all = false;
+ }
+ }
+
+ return found_all;
+ }
+
+}; // class IndexSearch
+
+enum return_code : int {
+ okay = 0,
+ not_found = 1,
+ error = 2,
+ fatal = 3
+};
+
+class Options {
+
+ std::vector<osmium::unsigned_object_id_type> m_ids;
+ std::string m_type;
+ std::string m_filename;
+ bool m_dump = false;
+ bool m_array_format = false;
+ bool m_list_format = false;
+
+ void print_help() {
+ std::cout << "Usage: osmium_index [OPTIONS]\n\n"
+ << "-h, --help Print this help message\n"
+ << "-a, --array=FILE Read given index file in array format\n"
+ << "-l, --list=FILE Read given index file in list format\n"
+ << "-d, --dump Dump contents of index file to STDOUT\n"
+ << "-s, --search=ID Search for given id (Option can appear multiple times)\n"
+ << "-t, --type=TYPE Type of value ('location' or 'offset')\n"
+ ;
+ }
+
+public:
+
+ Options(int argc, char* argv[]) {
+ static struct option long_options[] = {
+ {"array", required_argument, 0, 'a'},
+ {"dump", no_argument, 0, 'd'},
+ {"help", no_argument, 0, 'h'},
+ {"list", required_argument, 0, 'l'},
+ {"search", required_argument, 0, 's'},
+ {"type", required_argument, 0, 't'},
+ {0, 0, 0, 0}
+ };
+
+ while (true) {
+ int c = getopt_long(argc, argv, "a:dhl:s:t:", long_options, 0);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'a':
+ m_array_format = true;
+ m_filename = optarg;
+ break;
+ case 'd':
+ m_dump = true;
+ break;
+ case 'h':
+ print_help();
+ std::exit(return_code::okay);
+ case 'l':
+ m_list_format = true;
+ m_filename = optarg;
+ break;
+ case 's':
+ m_ids.push_back(std::atoll(optarg));
+ break;
+ case 't':
+ m_type = optarg;
+ if (m_type != "location" && m_type != "offset") {
+ std::cerr << "Unknown type '" << m_type << "'. Must be 'location' or 'offset'.\n";
+ std::exit(return_code::fatal);
+ }
+ break;
+ default:
+ std::exit(return_code::fatal);
+ }
+ }
+
+ if (m_array_format == m_list_format) {
+ std::cerr << "Need option --array or --list, but not both\n";
+ std::exit(return_code::fatal);
+ }
+
+ if (m_type.empty()) {
+ std::cerr << "Need --type argument.\n";
+ std::exit(return_code::fatal);
+ }
+
+ }
+
+ const std::string& filename() const noexcept {
+ return m_filename;
+ }
+
+ bool dense_format() const noexcept {
+ return m_array_format;
+ }
+
+ bool do_dump() const noexcept {
+ return m_dump;
+ }
+
+ const std::vector<osmium::unsigned_object_id_type>& search_keys() const noexcept {
+ return m_ids;
+ }
+
+ bool type_is(const char* type) const noexcept {
+ return m_type == type;
+ }
+
+}; // class Options
+
+int main(int argc, char* argv[]) {
+ std::ios_base::sync_with_stdio(false);
+
+ Options options(argc, argv);
+
+ std::cout << std::fixed << std::setprecision(7);
+ int fd = open(options.filename().c_str(), O_RDWR);
+
+ bool result_okay = true;
+
+ if (options.type_is("location")) {
+ IndexSearch<osmium::unsigned_object_id_type, osmium::Location> is(fd, options.dense_format());
+
+ if (options.do_dump()) {
+ is.dump();
+ } else {
+ result_okay = is.search(options.search_keys());
+ }
+ } else {
+ IndexSearch<osmium::unsigned_object_id_type, size_t> is(fd, options.dense_format());
+
+ if (options.do_dump()) {
+ is.dump();
+ } else {
+ result_okay = is.search(options.search_keys());
+ }
+ }
+
+ std::exit(result_okay ? return_code::okay : return_code::not_found);
+}
+
diff --git a/examples/osmium_index_lookup.cpp b/examples/osmium_index_lookup.cpp
deleted file mode 100644
index 01d7e36..0000000
--- a/examples/osmium_index_lookup.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
-
- EXAMPLE osmium_index
-
- Example program to look at Osmium indexes on disk.
-
- You can use the osmium_dump_internal example program to create the offset
- indexes or osmium_location_cache_create to create a node location index.
-
- DEMONSTRATES USE OF:
- * access to indexes on disk
-
- SIMPLER EXAMPLES you might want to understand first:
- * osmium_read
- * osmium_count
- * osmium_road_length
- * osmium_location_cache_create
- * osmium_location_cache_use
-
- LICENSE
- The code in this example file is released into the Public Domain.
-
-*/
-
-#include <algorithm> // for std::all_of, std::equal_range
-#include <cstdlib> // for std::exit
-#include <fcntl.h> // for open
-#include <getopt.h> // for getopt_long
-#include <iostream> // for std::cout, std::cerr
-#include <memory> // for std::unique_ptr
-#include <string> // for std::string
-#include <sys/stat.h> // for open
-#include <sys/types.h> // for open
-#include <vector> // for std::vector
-
-// Disk-based indexes
-#include <osmium/index/map/dense_file_array.hpp>
-#include <osmium/index/map/sparse_file_array.hpp>
-
-// osmium::Location
-#include <osmium/osm/location.hpp>
-
-// Basic Osmium types
-#include <osmium/osm/types.hpp>
-
-// Virtual class for disk index access. If offers functions to dump the
-// indexes and to search for ids in the index.
-template <typename TValue>
-class IndexAccess {
-
- int m_fd;
-
-public:
-
- IndexAccess(int fd) :
- m_fd(fd) {
- }
-
- int fd() const noexcept {
- return m_fd;
- }
-
- virtual ~IndexAccess() = default;
-
- virtual void dump() const = 0;
-
- virtual bool search(const osmium::unsigned_object_id_type& key) const = 0;
-
- bool search(const std::vector<osmium::unsigned_object_id_type>& keys) const {
- return std::all_of(keys.cbegin(), keys.cend(), [this](const osmium::unsigned_object_id_type& key) {
- return search(key);
- });
- }
-
-}; // class IndexAccess
-
-// Implementation of IndexAccess for dense indexes usually used for very large
-// extracts or the planet.
-template <typename TValue>
-class IndexAccessDense : public IndexAccess<TValue> {
-
- using index_type = typename osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, TValue>;
-
-public:
-
- IndexAccessDense(int fd) :
- IndexAccess<TValue>(fd) {
- }
-
- void dump() const override {
- index_type index{this->fd()};
-
- for (std::size_t i = 0; i < index.size(); ++i) {
- if (index.get(i) != TValue{}) {
- std::cout << i << " " << index.get(i) << "\n";
- }
- }
- }
-
- bool search(const osmium::unsigned_object_id_type& key) const override {
- index_type index{this->fd()};
-
- try {
- TValue value = index.get(key);
- std::cout << key << " " << value << "\n";
- } catch (...) {
- std::cout << key << " not found\n";
- return false;
- }
-
- return true;
- }
-
-}; // class IndexAccessDense
-
-// Implementation of IndexAccess for sparse indexes usually used for small or
-// medium sized extracts or for "multimap" type indexes.
-template <typename TValue>
-class IndexAccessSparse : public IndexAccess<TValue> {
-
- using index_type = typename osmium::index::map::SparseFileArray<osmium::unsigned_object_id_type, TValue>;
-
-public:
-
- IndexAccessSparse(int fd) :
- IndexAccess<TValue>(fd) {
- }
-
- void dump() const override {
- index_type index{this->fd()};
-
- for (const auto& element : index) {
- std::cout << element.first << " " << element.second << "\n";
- }
- }
-
- bool search(const osmium::unsigned_object_id_type& key) const override {
- using element_type = typename index_type::element_type;
- index_type index{this->fd()};
-
- element_type elem{key, TValue{}};
- const auto positions = std::equal_range(index.begin(),
- index.end(),
- elem,
- [](const element_type& lhs,
- const element_type& rhs) {
- return lhs.first < rhs.first;
- });
- if (positions.first == positions.second) {
- std::cout << key << " not found\n";
- return false;
- }
-
- for (auto it = positions.first; it != positions.second; ++it) {
- std::cout << it->first << " " << it->second << "\n";
- }
-
- return true;
- }
-
-}; // class IndexAccessSparse
-
-// This class contains the code to parse the command line arguments, check
-// them and present the results to the rest of the program in an easy-to-use
-// way.
-class Options {
-
- std::vector<osmium::unsigned_object_id_type> m_ids;
- std::string m_type;
- std::string m_filename;
- bool m_dump = false;
- bool m_array_format = false;
- bool m_list_format = false;
-
- void print_help() {
- std::cout << "Usage: osmium_index_lookup [OPTIONS]\n\n"
- << "-h, --help Print this help message\n"
- << "-a, --array=FILE Read given index file in array format\n"
- << "-l, --list=FILE Read given index file in list format\n"
- << "-d, --dump Dump contents of index file to STDOUT\n"
- << "-s, --search=ID Search for given id (Option can appear multiple times)\n"
- << "-t, --type=TYPE Type of value ('location', 'id', or 'offset')\n"
- ;
- }
-
-public:
-
- Options(int argc, char* argv[]) {
- if (argc == 1) {
- print_help();
- std::exit(1);
- }
-
- static struct option long_options[] = {
- {"array", required_argument, 0, 'a'},
- {"dump", no_argument, 0, 'd'},
- {"help", no_argument, 0, 'h'},
- {"list", required_argument, 0, 'l'},
- {"search", required_argument, 0, 's'},
- {"type", required_argument, 0, 't'},
- {0, 0, 0, 0}
- };
-
- while (true) {
- const int c = getopt_long(argc, argv, "a:dhl:s:t:", long_options, 0);
- if (c == -1) {
- break;
- }
-
- switch (c) {
- case 'a':
- m_array_format = true;
- m_filename = optarg;
- break;
- case 'd':
- m_dump = true;
- break;
- case 'h':
- print_help();
- std::exit(0);
- case 'l':
- m_list_format = true;
- m_filename = optarg;
- break;
- case 's':
- m_ids.push_back(std::atoll(optarg));
- break;
- case 't':
- m_type = optarg;
- if (m_type != "location" && m_type != "id" && m_type != "offset") {
- std::cerr << "Unknown type '" << m_type
- << "'. Must be 'location', 'id', or 'offset'.\n";
- std::exit(2);
- }
- break;
- default:
- std::exit(2);
- }
- }
-
- if (m_array_format == m_list_format) {
- std::cerr << "Need option --array or --list, but not both\n";
- std::exit(2);
- }
-
- if (m_dump && !m_ids.empty()) {
- std::cerr << "Need option --dump or --search, but not both\n";
- std::exit(2);
- }
-
- if (m_type.empty()) {
- std::cerr << "Need --type argument.\n";
- std::exit(2);
- }
-
- }
-
- const char* filename() const noexcept {
- return m_filename.c_str();
- }
-
- bool dense_format() const noexcept {
- return m_array_format;
- }
-
- bool do_dump() const noexcept {
- return m_dump;
- }
-
- const std::vector<osmium::unsigned_object_id_type>& search_keys() const noexcept {
- return m_ids;
- }
-
- bool type_is(const char* type) const noexcept {
- return m_type == type;
- }
-
-}; // class Options
-
-
-// Factory function to create the right IndexAccess-derived class.
-template <typename TValue>
-std::unique_ptr<IndexAccess<TValue>> create(bool dense, int fd) {
- std::unique_ptr<IndexAccess<TValue>> ptr;
-
- if (dense) {
- ptr.reset(new IndexAccessDense<TValue>{fd});
- } else {
- ptr.reset(new IndexAccessSparse<TValue>{fd});
- }
-
- return ptr;
-}
-
-// Do the actual work: Either dump the index or search in the index.
-template <typename TValue>
-int run(const IndexAccess<TValue>& index, const Options& options) {
- if (options.do_dump()) {
- index.dump();
- return 0;
- } else {
- return index.search(options.search_keys()) ? 0 : 1;
- }
-}
-
-int main(int argc, char* argv[]) {
- // Parse command line options.
- Options options{argc, argv};
-
- // Open the index file.
- const int fd = open(options.filename(), O_RDWR);
- if (fd < 0) {
- std::cerr << "Can not open file '" << options.filename()
- << "': " << std::strerror(errno) << '\n';
- std::exit(2);
- }
-
- // Depending on the type of index, we have different implementations.
- if (options.type_is("location")) {
- // index id -> location
- const auto index = create<osmium::Location>(options.dense_format(), fd);
- return run(*index, options);
- } else if (options.type_is("id")) {
- // index id -> id
- const auto index = create<osmium::unsigned_object_id_type>(options.dense_format(), fd);
- return run(*index, options);
- } else {
- // index id -> offset
- const auto index = create<std::size_t>(options.dense_format(), fd);
- return run(*index, options);
- }
-}
-
diff --git a/examples/osmium_pub_names.cpp b/examples/osmium_pub_names.cpp
old mode 100644
new mode 100755
diff --git a/examples/osmium_road_length.cpp b/examples/osmium_road_length.cpp
old mode 100644
new mode 100755
diff --git a/examples/osmium_serdump.cpp b/examples/osmium_serdump.cpp
new file mode 100644
index 0000000..81a6d0c
--- /dev/null
+++ b/examples/osmium_serdump.cpp
@@ -0,0 +1,206 @@
+/*
+
+ This is a small tool to dump the contents of the input file
+ in serialized format to stdout.
+
+ The code in this example file is released into the Public Domain.
+
+*/
+
+#include <cerrno>
+#include <cstring>
+#include <getopt.h>
+#include <iostream>
+#include <string>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifdef _MSC_VER
+# include <direct.h>
+#endif
+
+#include <osmium/io/any_input.hpp>
+#include <osmium/handler/disk_store.hpp>
+#include <osmium/handler/object_relations.hpp>
+
+#include <osmium/index/map/sparse_mem_array.hpp>
+#include <osmium/index/multimap/sparse_mem_multimap.hpp>
+#include <osmium/index/multimap/sparse_mem_array.hpp>
+#include <osmium/index/multimap/hybrid.hpp>
+
+// ==============================================================================
+// Choose the following depending on the size of the input OSM files:
+// ==============================================================================
+// for smaller OSM files (extracts)
+typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, size_t> offset_index_type;
+//typedef osmium::index::map::SparseMapMmap<osmium::unsigned_object_id_type, size_t> offset_index_type;
+//typedef osmium::index::map::SparseMapFile<osmium::unsigned_object_id_type, size_t> offset_index_type;
+
+typedef osmium::index::multimap::SparseMemArray<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type> map_type;
+//typedef osmium::index::multimap::SparseMemMultimap<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type> map_type;
+//typedef osmium::index::multimap::Hybrid<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type> map_type;
+
+// ==============================================================================
+// for very large OSM files (planet)
+//typedef osmium::index::map::DenseMmapArray<osmium::unsigned_object_id_type, size_t> offset_index_type;
+// ==============================================================================
+
+void print_help() {
+ std::cout << "osmium_serdump OSMFILE DIR\n" \
+ << "Serialize content of OSMFILE into data file in DIR.\n" \
+ << "\nOptions:\n" \
+ << " -h, --help This help message\n";
+}
+
+int main(int argc, char* argv[]) {
+ std::ios_base::sync_with_stdio(false);
+
+ static struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0}
+ };
+
+ while (true) {
+ int c = getopt_long(argc, argv, "h", long_options, 0);
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'h':
+ print_help();
+ std::exit(0);
+ default:
+ std::exit(2);
+ }
+ }
+
+ int remaining_args = argc - optind;
+
+ if (remaining_args != 2) {
+ std::cerr << "Usage: " << argv[0] << " OSMFILE DIR\n";
+ std::exit(2);
+ }
+
+ std::string dir(argv[optind+1]);
+#ifndef _WIN32
+ int result = ::mkdir(dir.c_str(), 0777);
+#else
+ int result = mkdir(dir.c_str());
+#endif
+ if (result == -1 && errno != EEXIST) {
+ std::cerr << "Problem creating directory '" << dir << "': " << strerror(errno) << "\n";
+ std::exit(2);
+ }
+
+ std::string data_file(dir + "/data.osm.ser");
+ int data_fd = ::open(data_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (data_fd < 0) {
+ std::cerr << "Can't open data file '" << data_file << "': " << strerror(errno) << "\n";
+ std::exit(2);
+ }
+
+ offset_index_type node_index;
+ offset_index_type way_index;
+ offset_index_type relation_index;
+
+ osmium::handler::DiskStore disk_store_handler(data_fd, node_index, way_index, relation_index);
+
+ map_type map_node2way;
+ map_type map_node2relation;
+ map_type map_way2relation;
+ map_type map_relation2relation;
+
+ osmium::handler::ObjectRelations object_relations_handler(map_node2way, map_node2relation, map_way2relation, map_relation2relation);
+
+ osmium::io::Reader reader(argv[1]);
+
+ while (osmium::memory::Buffer buffer = reader.read()) {
+ disk_store_handler(buffer); // XXX
+ osmium::apply(buffer, object_relations_handler);
+ }
+
+ reader.close();
+
+ {
+ std::string index_file(dir + "/nodes.idx");
+ int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0) {
+ std::cerr << "Can't open nodes index file '" << index_file << "': " << strerror(errno) << "\n";
+ std::exit(2);
+ }
+ node_index.dump_as_list(fd);
+ close(fd);
+ }
+
+ {
+ std::string index_file(dir + "/ways.idx");
+ int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0) {
+ std::cerr << "Can't open ways index file '" << index_file << "': " << strerror(errno) << "\n";
+ std::exit(2);
+ }
+ way_index.dump_as_list(fd);
+ close(fd);
+ }
+
+ {
+ std::string index_file(dir + "/relations.idx");
+ int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0) {
+ std::cerr << "Can't open relations index file '" << index_file << "': " << strerror(errno) << "\n";
+ std::exit(2);
+ }
+ relation_index.dump_as_list(fd);
+ close(fd);
+ }
+
+ {
+ map_node2way.sort();
+ std::string index_file(dir + "/node2way.map");
+ int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0) {
+ std::cerr << "Can't open node->way map file '" << index_file << "': " << strerror(errno) << "\n";
+ std::exit(2);
+ }
+ map_node2way.dump_as_list(fd);
+ close(fd);
+ }
+
+ {
+ map_node2relation.sort();
+ std::string index_file(dir + "/node2rel.map");
+ int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0) {
+ std::cerr << "Can't open node->rel map file '" << index_file << "': " << strerror(errno) << "\n";
+ std::exit(2);
+ }
+ map_node2relation.dump_as_list(fd);
+ close(fd);
+ }
+
+ {
+ map_way2relation.sort();
+ std::string index_file(dir + "/way2rel.map");
+ int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0) {
+ std::cerr << "Can't open way->rel map file '" << index_file << "': " << strerror(errno) << "\n";
+ std::exit(2);
+ }
+ map_way2relation.dump_as_list(fd);
+ close(fd);
+ }
+
+ {
+ map_relation2relation.sort();
+ std::string index_file(dir + "/rel2rel.map");
+ int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0) {
+ std::cerr << "Can't open rel->rel map file '" << index_file << "': " << strerror(errno) << "\n";
+ std::exit(2);
+ }
+ map_relation2relation.dump_as_list(fd);
+ close(fd);
+ }
+}
+
diff --git a/include/osmium/area/assembler.hpp b/include/osmium/area/assembler.hpp
index 092f4b4..d5bf8d8 100644
--- a/include/osmium/area/assembler.hpp
+++ b/include/osmium/area/assembler.hpp
@@ -193,12 +193,12 @@ namespace osmium {
}; // struct location_to_ring_map
- inline bool operator==(const location_to_ring_map& lhs, const location_to_ring_map& rhs) noexcept {
- return lhs.location == rhs.location;
+ inline bool operator==(const location_to_ring_map& a, const location_to_ring_map& b) noexcept {
+ return a.location == b.location;
}
- inline bool operator<(const location_to_ring_map& lhs, const location_to_ring_map& rhs) noexcept {
- return lhs.location < rhs.location;
+ inline bool operator<(const location_to_ring_map& a, const location_to_ring_map& b) noexcept {
+ return a.location < b.location;
}
} // namespace detail
@@ -288,7 +288,7 @@ namespace osmium {
}
void add_tags_to_area(osmium::builder::AreaBuilder& builder, const osmium::Way& way) const {
- builder.add_item(way.tags());
+ builder.add_item(&way.tags());
}
void add_common_tags(osmium::builder::TagListBuilder& tl_builder, std::set<const osmium::Way*>& ways) const {
@@ -333,7 +333,7 @@ namespace osmium {
}
static void copy_tags_without_type(osmium::builder::AreaBuilder& builder, const osmium::TagList& tags) {
- osmium::builder::TagListBuilder tl_builder{builder};
+ osmium::builder::TagListBuilder tl_builder(builder.buffer(), &builder);
for (const osmium::Tag& tag : tags) {
if (std::strcmp(tag.key(), "type")) {
tl_builder.add_tag(tag.key(), tag.value());
@@ -354,7 +354,7 @@ namespace osmium {
}
if (m_config.keep_type_tag) {
- builder.add_item(relation.tags());
+ builder.add_item(&relation.tags());
} else {
copy_tags_without_type(builder, relation.tags());
}
@@ -373,12 +373,12 @@ namespace osmium {
if (debug()) {
std::cerr << " only one outer way\n";
}
- builder.add_item((*ways.cbegin())->tags());
+ builder.add_item(&(*ways.cbegin())->tags());
} else {
if (debug()) {
std::cerr << " multiple outer ways, get common tags\n";
}
- osmium::builder::TagListBuilder tl_builder{builder};
+ osmium::builder::TagListBuilder tl_builder(builder.buffer(), &builder);
add_common_tags(tl_builder, ways);
}
}
@@ -386,7 +386,7 @@ namespace osmium {
template <typename TBuilder>
static void build_ring_from_proto_ring(osmium::builder::AreaBuilder& builder, const detail::ProtoRing& ring) {
- TBuilder ring_builder{builder};
+ TBuilder ring_builder(builder.buffer(), &builder);
ring_builder.add_node_ref(ring.get_node_ref_start());
for (const auto& segment : ring.segments()) {
ring_builder.add_node_ref(segment->stop());
@@ -458,8 +458,8 @@ namespace osmium {
}
detail::NodeRefSegment* get_next_segment(const osmium::Location& location) {
- auto it = std::lower_bound(m_locations.begin(), m_locations.end(), slocation{}, [this, &location](const slocation& lhs, const slocation& rhs) {
- return lhs.location(m_segment_list, location) < rhs.location(m_segment_list, location);
+ auto it = std::lower_bound(m_locations.begin(), m_locations.end(), slocation{}, [this, &location](const slocation& a, const slocation& b) {
+ return a.location(m_segment_list, location) < b.location(m_segment_list, location);
});
assert(it != m_locations.end());
@@ -744,8 +744,8 @@ namespace osmium {
m_locations.emplace_back(n, true);
}
- std::stable_sort(m_locations.begin(), m_locations.end(), [this](const slocation& lhs, const slocation& rhs) {
- return lhs.location(m_segment_list) < rhs.location(m_segment_list);
+ std::stable_sort(m_locations.begin(), m_locations.end(), [this](const slocation& a, const slocation& b) {
+ return a.location(m_segment_list) < b.location(m_segment_list);
});
}
@@ -1015,8 +1015,8 @@ namespace osmium {
std::vector<location_to_ring_map> xrings = create_location_to_ring_map(open_ring_its);
- const auto ring_min = std::min_element(xrings.begin(), xrings.end(), [](const location_to_ring_map& lhs, const location_to_ring_map& rhs) {
- return lhs.ring().min_segment() < rhs.ring().min_segment();
+ const auto ring_min = std::min_element(xrings.begin(), xrings.end(), [](const location_to_ring_map& a, const location_to_ring_map& b) {
+ return a.ring().min_segment() < b.ring().min_segment();
});
find_inner_outer_complex();
@@ -1068,11 +1068,11 @@ namespace osmium {
// Find the candidate with the smallest/largest area
const auto chosen_cand = ring_min_is_outer ?
- std::min_element(candidates.cbegin(), candidates.cend(), [](const candidate& lhs, const candidate& rhs) {
- return std::abs(lhs.sum) < std::abs(rhs.sum);
+ std::min_element(candidates.cbegin(), candidates.cend(), [](const candidate& a, const candidate& b) {
+ return std::abs(a.sum) < std::abs(b.sum);
}) :
- std::max_element(candidates.cbegin(), candidates.cend(), [](const candidate& lhs, const candidate& rhs) {
- return std::abs(lhs.sum) < std::abs(rhs.sum);
+ std::max_element(candidates.cbegin(), candidates.cend(), [](const candidate& a, const candidate& b) {
+ return std::abs(a.sum) < std::abs(b.sum);
});
if (debug()) {
@@ -1103,8 +1103,8 @@ namespace osmium {
const auto locs = make_range(std::equal_range(m_locations.begin(),
m_locations.end(),
slocation{},
- [this, &location](const slocation& lhs, const slocation& rhs) {
- return lhs.location(m_segment_list, location) < rhs.location(m_segment_list, location);
+ [this, &location](const slocation& a, const slocation& b) {
+ return a.location(m_segment_list, location) < b.location(m_segment_list, location);
}));
for (auto& loc : locs) {
if (!m_segment_list[loc.item].is_done()) {
@@ -1267,8 +1267,8 @@ namespace osmium {
}
for (const auto& location : m_split_locations) {
if (m_config.problem_reporter) {
- auto it = std::lower_bound(m_locations.cbegin(), m_locations.cend(), slocation{}, [this, &location](const slocation& lhs, const slocation& rhs) {
- return lhs.location(m_segment_list, location) < rhs.location(m_segment_list, location);
+ auto it = std::lower_bound(m_locations.cbegin(), m_locations.cend(), slocation{}, [this, &location](const slocation& a, const slocation& b) {
+ return a.location(m_segment_list, location) < b.location(m_segment_list, location);
});
assert(it != m_locations.cend());
const osmium::object_id_type id = it->node_ref(m_segment_list).ref();
@@ -1362,7 +1362,7 @@ namespace osmium {
#endif
bool create_area(osmium::memory::Buffer& out_buffer, const osmium::Way& way) {
- osmium::builder::AreaBuilder builder{out_buffer};
+ osmium::builder::AreaBuilder builder(out_buffer);
builder.initialize_from_object(way);
const bool area_okay = create_rings();
@@ -1382,7 +1382,7 @@ namespace osmium {
bool create_area(osmium::memory::Buffer& out_buffer, const osmium::Relation& relation, const std::vector<const osmium::Way*>& members) {
m_num_members = members.size();
- osmium::builder::AreaBuilder builder{out_buffer};
+ osmium::builder::AreaBuilder builder(out_buffer);
builder.initialize_from_object(relation);
const bool area_okay = create_rings();
diff --git a/include/osmium/area/detail/node_ref_segment.hpp b/include/osmium/area/detail/node_ref_segment.hpp
index 1c03d3e..b131a43 100644
--- a/include/osmium/area/detail/node_ref_segment.hpp
+++ b/include/osmium/area/detail/node_ref_segment.hpp
@@ -379,8 +379,8 @@ namespace osmium {
sl[2] = {1, s2.first().location() };
sl[3] = {1, s2.second().location()};
- std::sort(sl, sl+4, [](const seg_loc& lhs, const seg_loc& rhs) {
- return lhs.location < rhs.location;
+ std::sort(sl, sl+4, [](const seg_loc& a, const seg_loc& b) {
+ return a.location < b.location;
});
if (sl[1].location == sl[2].location) {
diff --git a/include/osmium/area/detail/segment_list.hpp b/include/osmium/area/detail/segment_list.hpp
index 97d512a..a4361e0 100644
--- a/include/osmium/area/detail/segment_list.hpp
+++ b/include/osmium/area/detail/segment_list.hpp
@@ -101,7 +101,7 @@ namespace osmium {
* Calculate the number of segments in all the ways together.
*/
static size_t get_num_segments(const std::vector<const osmium::Way*>& members) noexcept {
- return std::accumulate(members.cbegin(), members.cend(), static_cast<size_t>(0), [](size_t sum, const osmium::Way* way) {
+ return std::accumulate(members.cbegin(), members.cend(), 0, [](size_t sum, const osmium::Way* way) {
if (way->nodes().empty()) {
return sum;
} else {
diff --git a/include/osmium/area/detail/vector.hpp b/include/osmium/area/detail/vector.hpp
index fae1280..44983cc 100644
--- a/include/osmium/area/detail/vector.hpp
+++ b/include/osmium/area/detail/vector.hpp
@@ -73,18 +73,18 @@ namespace osmium {
}; // struct vec
// addition
- constexpr inline vec operator+(const vec& lhs, const vec& rhs) noexcept {
- return vec{lhs.x + rhs.x, lhs.y + rhs.y};
+ constexpr inline vec operator+(const vec& a, const vec& b) noexcept {
+ return vec{a.x + b.x, a.y + b.y};
}
// subtraction
- constexpr inline vec operator-(const vec& lhs, const vec& rhs) noexcept {
- return vec{lhs.x - rhs.x, lhs.y - rhs.y};
+ constexpr inline vec operator-(const vec& a, const vec& b) noexcept {
+ return vec{a.x - b.x, a.y - b.y};
}
// cross product
- constexpr inline int64_t operator*(const vec& lhs, const vec& rhs) noexcept {
- return lhs.x * rhs.y - lhs.y * rhs.x;
+ constexpr inline int64_t operator*(const vec& a, const vec& b) noexcept {
+ return a.x * b.y - a.y * b.x;
}
// scale vector
@@ -98,13 +98,13 @@ namespace osmium {
}
// equality
- constexpr inline bool operator==(const vec& lhs, const vec& rhs) noexcept {
- return lhs.x == rhs.x && lhs.y == rhs.y;
+ constexpr inline bool operator==(const vec& a, const vec& b) noexcept {
+ return a.x == b.x && a.y == b.y;
}
// inequality
- constexpr inline bool operator!=(const vec& lhs, const vec& rhs) noexcept {
- return !(lhs == rhs);
+ constexpr inline bool operator!=(const vec& a, const vec& b) noexcept {
+ return !(a == b);
}
template <typename TChar, typename TTraits>
diff --git a/include/osmium/builder/attr.hpp b/include/osmium/builder/attr.hpp
index 8e0b4a3..2a5b690 100644
--- a/include/osmium/builder/attr.hpp
+++ b/include/osmium/builder/attr.hpp
@@ -617,7 +617,7 @@ namespace osmium {
template <typename TBuilder, typename... TArgs>
inline void add_user(TBuilder& builder, const TArgs&... args) {
- builder.set_user(get_user(args...));
+ builder.add_user(get_user(args...));
}
// ==============================================================
@@ -761,13 +761,11 @@ namespace osmium {
static_assert(sizeof...(args) > 0, "add_node() must have buffer and at least one additional argument");
static_assert(detail::are_all_handled_by<detail::any_node_handlers, TArgs...>::value, "Attribute not allowed in add_node()");
- {
- NodeBuilder builder(buffer);
+ NodeBuilder builder(buffer);
- detail::add_basic<detail::node_handler>(builder, args...);
- detail::add_user(builder, args...);
- detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
- }
+ detail::add_basic<detail::node_handler>(builder, args...);
+ detail::add_user(builder, args...);
+ detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
return buffer.commit();
}
@@ -784,14 +782,12 @@ namespace osmium {
static_assert(sizeof...(args) > 0, "add_way() must have buffer and at least one additional argument");
static_assert(detail::are_all_handled_by<detail::any_way_handlers, TArgs...>::value, "Attribute not allowed in add_way()");
- {
- WayBuilder builder(buffer);
+ WayBuilder builder(buffer);
- detail::add_basic<detail::object_handler>(builder, args...);
- detail::add_user(builder, args...);
- detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
- detail::add_list<WayNodeListBuilder, detail::nodes_handler>(builder, args...);
- }
+ detail::add_basic<detail::object_handler>(builder, args...);
+ detail::add_user(builder, args...);
+ detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
+ detail::add_list<WayNodeListBuilder, detail::nodes_handler>(builder, args...);
return buffer.commit();
}
@@ -808,14 +804,12 @@ namespace osmium {
static_assert(sizeof...(args) > 0, "add_relation() must have buffer and at least one additional argument");
static_assert(detail::are_all_handled_by<detail::any_relation_handlers, TArgs...>::value, "Attribute not allowed in add_relation()");
- {
- RelationBuilder builder(buffer);
+ RelationBuilder builder(buffer);
- detail::add_basic<detail::object_handler>(builder, args...);
- detail::add_user(builder, args...);
- detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
- detail::add_list<RelationMemberListBuilder, detail::members_handler>(builder, args...);
- }
+ detail::add_basic<detail::object_handler>(builder, args...);
+ detail::add_user(builder, args...);
+ detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
+ detail::add_list<RelationMemberListBuilder, detail::members_handler>(builder, args...);
return buffer.commit();
}
@@ -832,14 +826,12 @@ namespace osmium {
static_assert(sizeof...(args) > 0, "add_changeset() must have buffer and at least one additional argument");
static_assert(detail::are_all_handled_by<detail::any_changeset_handlers, TArgs...>::value, "Attribute not allowed in add_changeset()");
- {
- ChangesetBuilder builder(buffer);
+ ChangesetBuilder builder(buffer);
- detail::add_basic<detail::changeset_handler>(builder, args...);
- detail::add_user(builder, args...);
- detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
- detail::add_list<ChangesetDiscussionBuilder, detail::discussion_handler>(builder, args...);
- }
+ detail::add_basic<detail::changeset_handler>(builder, args...);
+ detail::add_user(builder, args...);
+ detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
+ detail::add_list<ChangesetDiscussionBuilder, detail::discussion_handler>(builder, args...);
return buffer.commit();
}
@@ -856,17 +848,15 @@ namespace osmium {
static_assert(sizeof...(args) > 0, "add_area() must have buffer and at least one additional argument");
static_assert(detail::are_all_handled_by<detail::any_area_handlers, TArgs...>::value, "Attribute not allowed in add_area()");
- {
- AreaBuilder builder(buffer);
+ AreaBuilder builder(buffer);
- detail::add_basic<detail::object_handler>(builder, args...);
- detail::add_user(builder, args...);
- detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
+ detail::add_basic<detail::object_handler>(builder, args...);
+ detail::add_user(builder, args...);
+ detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
- (void)std::initializer_list<int>{
- (detail::ring_handler::set_value(builder, args), 0)...
- };
- }
+ (void)std::initializer_list<int>{
+ (detail::ring_handler::set_value(builder, args), 0)...
+ };
return buffer.commit();
}
diff --git a/include/osmium/builder/builder.hpp b/include/osmium/builder/builder.hpp
index 044da1e..1b274ad 100644
--- a/include/osmium/builder/builder.hpp
+++ b/include/osmium/builder/builder.hpp
@@ -45,7 +45,6 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/memory/item.hpp>
#include <osmium/osm/types.hpp>
#include <osmium/util/cast.hpp>
-#include <osmium/util/compatibility.hpp>
namespace osmium {
@@ -54,10 +53,6 @@ namespace osmium {
*/
namespace builder {
- /**
- * Parent class for individual builder classes. Instantiate one of
- * its derived classes.
- */
class Builder {
osmium::memory::Buffer& m_buffer;
@@ -76,34 +71,20 @@ namespace osmium {
m_buffer(buffer),
m_parent(parent),
m_item_offset(buffer.written()) {
- reserve_space(size);
+ m_buffer.reserve_space(size);
assert(buffer.is_aligned());
if (m_parent) {
- assert(m_buffer.builder_count() == 1 && "Only one sub-builder can be open at any time.");
m_parent->add_size(size);
- } else {
- assert(m_buffer.builder_count() == 0 && "Only one builder can be open at any time.");
}
-#ifndef NDEBUG
- m_buffer.increment_builder_count();
-#endif
}
-#ifdef NDEBUG
~Builder() = default;
-#else
- ~Builder() noexcept {
- m_buffer.decrement_builder_count();
- }
-#endif
osmium::memory::Item& item() const {
return *reinterpret_cast<osmium::memory::Item*>(m_buffer.data() + m_item_offset);
}
- unsigned char* reserve_space(size_t size) {
- return m_buffer.reserve_space(size);
- }
+ public:
/**
* Add padding to buffer (if needed) to align data properly.
@@ -121,7 +102,7 @@ namespace osmium {
void add_padding(bool self = false) {
const auto padding = osmium::memory::align_bytes - (size() % osmium::memory::align_bytes);
if (padding != osmium::memory::align_bytes) {
- std::fill_n(reserve_space(padding), padding, 0);
+ std::fill_n(m_buffer.reserve_space(padding), padding, 0);
if (self) {
add_size(padding);
} else if (m_parent) {
@@ -142,6 +123,12 @@ namespace osmium {
return item().byte_size();
}
+ void add_item(const osmium::memory::Item* item) {
+ unsigned char* target = m_buffer.reserve_space(item->padded_size());
+ std::copy_n(reinterpret_cast<const unsigned char*>(item), item->padded_size(), target);
+ add_size(item->padded_size());
+ }
+
/**
* Reserve space for an object of class T in buffer and return
* pointer to it.
@@ -149,7 +136,7 @@ namespace osmium {
template <typename T>
T* reserve_space_for() {
assert(m_buffer.is_aligned());
- return reinterpret_cast<T*>(reserve_space(sizeof(T)));
+ return reinterpret_cast<T*>(m_buffer.reserve_space(sizeof(T)));
}
/**
@@ -162,7 +149,7 @@ namespace osmium {
* @returns The number of bytes appended (length).
*/
osmium::memory::item_size_type append(const char* data, const osmium::memory::item_size_type length) {
- unsigned char* target = reserve_space(length);
+ unsigned char* target = m_buffer.reserve_space(length);
std::copy_n(reinterpret_cast<const unsigned char*>(data), length, target);
return length;
}
@@ -183,36 +170,64 @@ namespace osmium {
* @returns The number of bytes appended (always 1).
*/
osmium::memory::item_size_type append_zero() {
- *reserve_space(1) = '\0';
+ *m_buffer.reserve_space(1) = '\0';
return 1;
}
- public:
-
/// Return the buffer this builder is using.
osmium::memory::Buffer& buffer() noexcept {
return m_buffer;
}
+ }; // class Builder
+
+ template <typename TItem>
+ class ObjectBuilder : public Builder {
+
+ static_assert(std::is_base_of<osmium::memory::Item, TItem>::value, "ObjectBuilder can only build objects derived from osmium::memory::Item");
+
+ public:
+
+ explicit ObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
+ Builder(buffer, parent, sizeof(TItem)) {
+ new (&item()) TItem();
+ }
+
+ TItem& object() noexcept {
+ return static_cast<TItem&>(item());
+ }
+
+ /**
+ * Add user name to buffer.
+ *
+ * @param user Pointer to user name.
+ * @param length Length of user name (without \0 termination).
+ */
+ void add_user(const char* user, const string_size_type length) {
+ object().set_user_size(length + 1);
+ add_size(append(user, length) + append_zero());
+ add_padding(true);
+ }
+
/**
- * Add a subitem to the object being built. This can be something
- * like a TagList or RelationMemberList.
+ * Add user name to buffer.
+ *
+ * @param user Pointer to \0-terminated user name.
*/
- void add_item(const osmium::memory::Item& item) {
- m_buffer.add_item(item);
- add_size(item.padded_size());
+ void add_user(const char* user) {
+ add_user(user, static_cast_with_assert<string_size_type>(std::strlen(user)));
}
/**
- * @deprecated Use the version of add_item() taking a
- * reference instead.
+ * Add user name to buffer.
+ *
+ * @param user User name.
*/
- OSMIUM_DEPRECATED void add_item(const osmium::memory::Item* item) {
- assert(item);
- add_item(*item);
+ void add_user(const std::string& user) {
+ add_user(user.data(), static_cast_with_assert<string_size_type>(user.size()));
}
- }; // class Builder
+ }; // class ObjectBuilder
} // namespace builder
diff --git a/include/osmium/builder/osm_object_builder.hpp b/include/osmium/builder/osm_object_builder.hpp
index b1c7220..e7a8298 100644
--- a/include/osmium/builder/osm_object_builder.hpp
+++ b/include/osmium/builder/osm_object_builder.hpp
@@ -45,7 +45,6 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/builder/builder.hpp>
#include <osmium/osm/item_type.hpp>
#include <osmium/osm/location.hpp>
-#include <osmium/osm/node.hpp>
#include <osmium/osm/node_ref.hpp>
#include <osmium/osm/object.hpp>
#include <osmium/osm/tag.hpp>
@@ -56,7 +55,6 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/relation.hpp>
#include <osmium/osm/timestamp.hpp>
#include <osmium/osm/way.hpp>
-#include <osmium/util/compatibility.hpp>
namespace osmium {
@@ -68,18 +66,12 @@ namespace osmium {
namespace builder {
- class TagListBuilder : public Builder {
+ class TagListBuilder : public ObjectBuilder<TagList> {
public:
explicit TagListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
- Builder(buffer, parent, sizeof(TagList)) {
- new (&item()) TagList();
- }
-
- explicit TagListBuilder(Builder& parent) :
- Builder(parent.buffer(), &parent, sizeof(TagList)) {
- new (&item()) TagList();
+ ObjectBuilder<TagList>(buffer, parent) {
}
~TagListBuilder() {
@@ -177,27 +169,21 @@ namespace osmium {
}; // class TagListBuilder
template <typename T>
- class NodeRefListBuilder : public Builder {
+ class NodeRefListBuilder : public ObjectBuilder<T> {
public:
explicit NodeRefListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
- Builder(buffer, parent, sizeof(T)) {
- new (&item()) T();
- }
-
- explicit NodeRefListBuilder(Builder& parent) :
- Builder(parent.buffer(), &parent, sizeof(T)) {
- new (&item()) T();
+ ObjectBuilder<T>(buffer, parent) {
}
~NodeRefListBuilder() {
- add_padding();
+ static_cast<Builder*>(this)->add_padding();
}
void add_node_ref(const NodeRef& node_ref) {
- new (reserve_space_for<osmium::NodeRef>()) osmium::NodeRef(node_ref);
- add_size(sizeof(osmium::NodeRef));
+ new (static_cast<Builder*>(this)->reserve_space_for<osmium::NodeRef>()) osmium::NodeRef(node_ref);
+ static_cast<Builder*>(this)->add_size(sizeof(osmium::NodeRef));
}
void add_node_ref(const object_id_type ref, const osmium::Location& location = Location{}) {
@@ -210,7 +196,7 @@ namespace osmium {
using OuterRingBuilder = NodeRefListBuilder<OuterRing>;
using InnerRingBuilder = NodeRefListBuilder<InnerRing>;
- class RelationMemberListBuilder : public Builder {
+ class RelationMemberListBuilder : public ObjectBuilder<RelationMemberList> {
/**
* Add role to buffer.
@@ -233,13 +219,7 @@ namespace osmium {
public:
explicit RelationMemberListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
- Builder(buffer, parent, sizeof(RelationMemberList)) {
- new (&item()) RelationMemberList();
- }
-
- explicit RelationMemberListBuilder(Builder& parent) :
- Builder(parent.buffer(), &parent, sizeof(RelationMemberList)) {
- new (&item()) RelationMemberList();
+ ObjectBuilder<RelationMemberList>(buffer, parent) {
}
~RelationMemberListBuilder() {
@@ -265,7 +245,7 @@ namespace osmium {
add_size(sizeof(RelationMember));
add_role(*member, role, role_length);
if (full_member) {
- add_item(*full_member);
+ add_item(full_member);
}
}
@@ -301,7 +281,7 @@ namespace osmium {
}; // class RelationMemberListBuilder
- class ChangesetDiscussionBuilder : public Builder {
+ class ChangesetDiscussionBuilder : public ObjectBuilder<ChangesetDiscussion> {
osmium::ChangesetComment* m_comment = nullptr;
@@ -329,13 +309,7 @@ namespace osmium {
public:
explicit ChangesetDiscussionBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
- Builder(buffer, parent, sizeof(ChangesetDiscussion)) {
- new (&item()) ChangesetDiscussion();
- }
-
- explicit ChangesetDiscussionBuilder(Builder& parent) :
- Builder(parent.buffer(), &parent, sizeof(ChangesetDiscussion)) {
- new (&item()) ChangesetDiscussion();
+ ObjectBuilder<ChangesetDiscussion>(buffer, parent) {
}
~ChangesetDiscussionBuilder() {
@@ -365,101 +339,19 @@ namespace osmium {
}; // class ChangesetDiscussionBuilder
-#define OSMIUM_FORWARD(setter) \
- template <typename... TArgs> \
- type& setter(TArgs&&... args) { \
- object().setter(std::forward<TArgs>(args)...); \
- return static_cast<type&>(*this); \
- }
-
- template <typename TDerived, typename T>
- class OSMObjectBuilder : public Builder {
-
- using type = TDerived;
-
- constexpr static const size_t min_size_for_user = osmium::memory::padded_length(sizeof(string_size_type) + 1);
+ template <typename T>
+ class OSMObjectBuilder : public ObjectBuilder<T> {
public:
explicit OSMObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
- Builder(buffer, parent, sizeof(T) + min_size_for_user) {
- new (&item()) T();
- add_size(min_size_for_user);
- std::fill_n(object().data() + sizeof(T), min_size_for_user, 0);
- object().set_user_size(1);
- }
-
- /**
- * Get a reference to the object buing built.
- *
- * Note that this reference will be invalidated by every action
- * on the builder that might make the buffer grow. This includes
- * calls to set_user() and any time a new sub-builder is created.
- */
- T& object() noexcept {
- return static_cast<T&>(item());
- }
-
- /**
- * Set user name.
- *
- * @param user Pointer to user name.
- * @param length Length of user name (without \0 termination).
- */
- TDerived& set_user(const char* user, const string_size_type length) {
- const auto size_of_object = sizeof(T) + sizeof(string_size_type);
- assert(object().user_size() == 1 && (size() <= size_of_object + osmium::memory::padded_length(1))
- && "set_user() must be called at most once and before any sub-builders");
- const auto available_space = min_size_for_user - sizeof(string_size_type) - 1;
- if (length > available_space) {
- const auto space_needed = osmium::memory::padded_length(length - available_space);
- reserve_space(space_needed);
- add_size(static_cast<uint32_t>(space_needed));
- }
- std::copy_n(user, length, object().data() + size_of_object);
- std::fill_n(object().data() + size_of_object + length, osmium::memory::padded_length(length + 1) - length, 0);
- object().set_user_size(length + 1);
-
- return static_cast<TDerived&>(*this);
+ ObjectBuilder<T>(buffer, parent) {
+ static_cast<Builder*>(this)->reserve_space_for<string_size_type>();
+ static_cast<Builder*>(this)->add_size(sizeof(string_size_type));
}
- /**
- * Set user name.
- *
- * @param user Pointer to \0-terminated user name.
- */
- TDerived& set_user(const char* user) {
- return set_user(user, static_cast_with_assert<string_size_type>(std::strlen(user)));
- }
-
- /**
- * Set user name.
- *
- * @param user User name.
- */
- TDerived& set_user(const std::string& user) {
- return set_user(user.data(), static_cast_with_assert<string_size_type>(user.size()));
- }
-
- /// @deprecated Use set_user(...) instead.
- template <typename... TArgs>
- OSMIUM_DEPRECATED void add_user(TArgs&&... args) {
- set_user(std::forward<TArgs>(args)...);
- }
-
- OSMIUM_FORWARD(set_id)
- OSMIUM_FORWARD(set_visible)
- OSMIUM_FORWARD(set_deleted)
- OSMIUM_FORWARD(set_version)
- OSMIUM_FORWARD(set_changeset)
- OSMIUM_FORWARD(set_uid)
- OSMIUM_FORWARD(set_uid_from_signed)
- OSMIUM_FORWARD(set_timestamp)
- OSMIUM_FORWARD(set_attribute)
- OSMIUM_FORWARD(set_removed)
-
void add_tags(const std::initializer_list<std::pair<const char*, const char*>>& tags) {
- osmium::builder::TagListBuilder tl_builder{buffer(), this};
+ osmium::builder::TagListBuilder tl_builder(static_cast<Builder*>(this)->buffer(), this);
for (const auto& p : tags) {
tl_builder.add_tag(p.first, p.second);
}
@@ -467,40 +359,19 @@ namespace osmium {
}; // class OSMObjectBuilder
- class NodeBuilder : public OSMObjectBuilder<NodeBuilder, Node> {
+ using NodeBuilder = OSMObjectBuilder<osmium::Node>;
+ using RelationBuilder = OSMObjectBuilder<osmium::Relation>;
- using type = NodeBuilder;
-
- public:
-
- explicit NodeBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
- OSMObjectBuilder<NodeBuilder, Node>(buffer, parent) {
- }
-
- explicit NodeBuilder(Builder& parent) :
- OSMObjectBuilder<NodeBuilder, Node>(parent.buffer(), &parent) {
- }
-
- OSMIUM_FORWARD(set_location)
-
- }; // class NodeBuilder
-
- class WayBuilder : public OSMObjectBuilder<WayBuilder, Way> {
-
- using type = WayBuilder;
+ class WayBuilder : public OSMObjectBuilder<osmium::Way> {
public:
explicit WayBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
- OSMObjectBuilder<WayBuilder, Way>(buffer, parent) {
- }
-
- explicit WayBuilder(Builder& parent) :
- OSMObjectBuilder<WayBuilder, Way>(parent.buffer(), &parent) {
+ OSMObjectBuilder<osmium::Way>(buffer, parent) {
}
void add_node_refs(const std::initializer_list<osmium::NodeRef>& nodes) {
- osmium::builder::WayNodeListBuilder builder{buffer(), this};
+ osmium::builder::WayNodeListBuilder builder(buffer(), this);
for (const auto& node_ref : nodes) {
builder.add_node_ref(node_ref);
}
@@ -508,147 +379,32 @@ namespace osmium {
}; // class WayBuilder
- class RelationBuilder : public OSMObjectBuilder<RelationBuilder, Relation> {
-
- using type = RelationBuilder;
-
- public:
-
- explicit RelationBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
- OSMObjectBuilder<RelationBuilder, Relation>(buffer, parent) {
- }
-
- explicit RelationBuilder(Builder& parent) :
- OSMObjectBuilder<RelationBuilder, Relation>(parent.buffer(), &parent) {
- }
-
- }; // class RelationBuilder
-
- class AreaBuilder : public OSMObjectBuilder<AreaBuilder, Area> {
-
- using type = AreaBuilder;
+ class AreaBuilder : public OSMObjectBuilder<osmium::Area> {
public:
explicit AreaBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
- OSMObjectBuilder<AreaBuilder, Area>(buffer, parent) {
- }
-
- explicit AreaBuilder(Builder& parent) :
- OSMObjectBuilder<AreaBuilder, Area>(parent.buffer(), &parent) {
+ OSMObjectBuilder<osmium::Area>(buffer, parent) {
}
/**
* Initialize area attributes from the attributes of the given object.
*/
void initialize_from_object(const osmium::OSMObject& source) {
- set_id(osmium::object_id_to_area_id(source.id(), source.type()));
- set_version(source.version());
- set_changeset(source.changeset());
- set_timestamp(source.timestamp());
- set_visible(source.visible());
- set_uid(source.uid());
- set_user(source.user());
- }
-
- }; // class AreaBuilder
-
- class ChangesetBuilder : public Builder {
-
- using type = ChangesetBuilder;
-
- constexpr static const size_t min_size_for_user = osmium::memory::padded_length(1);
-
- public:
-
- explicit ChangesetBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
- Builder(buffer, parent, sizeof(Changeset) + min_size_for_user) {
- new (&item()) Changeset();
- add_size(min_size_for_user);
- std::fill_n(object().data() + sizeof(Changeset), min_size_for_user, 0);
- object().set_user_size(1);
- }
-
- /**
- * Get a reference to the changeset buing built.
- *
- * Note that this reference will be invalidated by every action
- * on the builder that might make the buffer grow. This includes
- * calls to set_user() and any time a new sub-builder is created.
- */
- Changeset& object() noexcept {
- return static_cast<Changeset&>(item());
- }
+ osmium::Area& area = object();
+ area.set_id(osmium::object_id_to_area_id(source.id(), source.type()));
+ area.set_version(source.version());
+ area.set_changeset(source.changeset());
+ area.set_timestamp(source.timestamp());
+ area.set_visible(source.visible());
+ area.set_uid(source.uid());
- OSMIUM_FORWARD(set_id)
- OSMIUM_FORWARD(set_uid)
- OSMIUM_FORWARD(set_uid_from_signed)
- OSMIUM_FORWARD(set_created_at)
- OSMIUM_FORWARD(set_closed_at)
- OSMIUM_FORWARD(set_num_changes)
- OSMIUM_FORWARD(set_num_comments)
- OSMIUM_FORWARD(set_attribute)
- OSMIUM_FORWARD(set_removed)
-
- // @deprecated Use set_bounds() instead.
- OSMIUM_DEPRECATED osmium::Box& bounds() noexcept {
- return object().bounds();
+ add_user(source.user());
}
- ChangesetBuilder& set_bounds(const osmium::Box& box) noexcept {
- object().bounds() = box;
- return *this;
- }
-
- /**
- * Set user name.
- *
- * @param user Pointer to user name.
- * @param length Length of user name (without \0 termination).
- */
- ChangesetBuilder& set_user(const char* user, const string_size_type length) {
- assert(object().user_size() == 1 && (size() <= sizeof(Changeset) + osmium::memory::padded_length(1))
- && "set_user() must be called at most once and before any sub-builders");
- const auto available_space = min_size_for_user - 1;
- if (length > available_space) {
- const auto space_needed = osmium::memory::padded_length(length - available_space);
- reserve_space(space_needed);
- add_size(static_cast<uint32_t>(space_needed));
- }
- std::copy_n(user, length, object().data() + sizeof(Changeset));
- std::fill_n(object().data() + sizeof(Changeset) + length, osmium::memory::padded_length(length + 1) - length, 0);
- object().set_user_size(length + 1);
-
- return *this;
- }
-
- /**
- * Set user name.
- *
- * @param user Pointer to \0-terminated user name.
- */
- ChangesetBuilder& set_user(const char* user) {
- return set_user(user, static_cast_with_assert<string_size_type>(std::strlen(user)));
- }
-
- /**
- * Set user name.
- *
- * @param user User name.
- */
- ChangesetBuilder& set_user(const std::string& user) {
- return set_user(user.data(), static_cast_with_assert<string_size_type>(user.size()));
- }
-
- /// @deprecated Use set_user(...) instead.
- template <typename... TArgs>
- OSMIUM_DEPRECATED void add_user(TArgs&&... args) {
- set_user(std::forward<TArgs>(args)...);
- }
-
- }; // class ChangesetBuilder
+ }; // class AreaBuilder
-#undef OSMIUM_FORWARD
+ using ChangesetBuilder = ObjectBuilder<osmium::Changeset>;
} // namespace builder
diff --git a/include/osmium/geom/factory.hpp b/include/osmium/geom/factory.hpp
index f2db402..14c51df 100644
--- a/include/osmium/geom/factory.hpp
+++ b/include/osmium/geom/factory.hpp
@@ -95,7 +95,7 @@ namespace osmium {
return m_message.c_str();
}
- }; // class geometry_error
+ }; // struct geometry_error
/**
* @brief Everything related to geometry handling.
diff --git a/include/osmium/geom/geos.hpp b/include/osmium/geom/geos.hpp
index d59e7ce..f406076 100644
--- a/include/osmium/geom/geos.hpp
+++ b/include/osmium/geom/geos.hpp
@@ -33,22 +33,12 @@ DEALINGS IN THE SOFTWARE.
*/
-#include <geos/version.h>
-#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && (GEOS_VERSION_MAJOR < 3 || (GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR <= 5))
-
-#define OSMIUM_WITH_GEOS
-
/**
* @file
*
- * This file contains code for conversion of OSM geometries into GEOS
+ * This file contains code for conversion of OSM geometries into GDAL
* geometries.
*
- * Note that everything in this file is deprecated and only works up to
- * GEOS 3.5. It uses the GEOS C++ API which the GEOS project does not consider
- * to be a stable, external API. We probably should have used the GEOS C API
- * instead.
- *
* @attention If you include this file, you'll need to link with `libgeos`.
*/
@@ -98,7 +88,6 @@ namespace osmium {
namespace detail {
- /// @deprecated
class GEOSFactoryImpl {
std::unique_ptr<const geos::geom::PrecisionModel> m_precision_model;
@@ -256,7 +245,6 @@ namespace osmium {
} // namespace detail
- /// @deprecated
template <typename TProjection = IdentityProjection>
using GEOSFactory = GeometryFactory<osmium::geom::detail::GEOSFactoryImpl, TProjection>;
@@ -266,6 +254,4 @@ namespace osmium {
#undef THROW
-#endif
-
#endif // OSMIUM_GEOM_GEOS_HPP
diff --git a/include/osmium/geom/relations.hpp b/include/osmium/geom/relations.hpp
index 5e6e773..76d452e 100644
--- a/include/osmium/geom/relations.hpp
+++ b/include/osmium/geom/relations.hpp
@@ -43,11 +43,11 @@ namespace osmium {
/**
* Check whether one geometry contains another.
*/
- inline bool contains(const osmium::Box& lhs, const osmium::Box& rhs) {
- return ((lhs.bottom_left().x() >= rhs.bottom_left().x()) &&
- (lhs.top_right().x() <= rhs.top_right().x()) &&
- (lhs.bottom_left().y() >= rhs.bottom_left().y()) &&
- (lhs.top_right().y() <= rhs.top_right().y()));
+ inline bool contains(const osmium::Box& a, const osmium::Box& b) {
+ return ((a.bottom_left().x() >= b.bottom_left().x()) &&
+ (a.top_right().x() <= b.top_right().x()) &&
+ (a.bottom_left().y() >= b.bottom_left().y()) &&
+ (a.top_right().y() <= b.top_right().y()));
}
} // namespace geom
diff --git a/include/osmium/geom/tile.hpp b/include/osmium/geom/tile.hpp
index 2c33017..672ae54 100644
--- a/include/osmium/geom/tile.hpp
+++ b/include/osmium/geom/tile.hpp
@@ -118,23 +118,23 @@ namespace osmium {
}; // struct Tile
/// Tiles are equal if all their attributes are equal.
- inline bool operator==(const Tile& lhs, const Tile& rhs) {
- return lhs.z == rhs.z && lhs.x == rhs.x && lhs.y == rhs.y;
+ 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& lhs, const Tile& rhs) {
- return ! (lhs == rhs);
+ 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& lhs, const Tile& rhs) {
- if (lhs.z < rhs.z) return true;
- if (lhs.z > rhs.z) return false;
- if (lhs.x < rhs.x) return true;
- if (lhs.x > rhs.x) return false;
- return lhs.y < rhs.y;
+ 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
diff --git a/include/osmium/handler/disk_store.hpp b/include/osmium/handler/disk_store.hpp
index d112ac0..4e95573 100644
--- a/include/osmium/handler/disk_store.hpp
+++ b/include/osmium/handler/disk_store.hpp
@@ -51,9 +51,6 @@ namespace osmium {
namespace handler {
/**
- * Writes OSM data in the Osmium-internal serialized format to disk
- * keeping track of object offsets in the indexes given to the
- * constructor.
*
* Note: This handler will only work if either all object IDs are
* positive or all object IDs are negative.
@@ -98,8 +95,10 @@ namespace osmium {
m_offset += relation.byte_size();
}
+ // XXX
void operator()(const osmium::memory::Buffer& buffer) {
osmium::io::detail::reliable_write(m_data_fd, buffer.data(), buffer.committed());
+
osmium::apply(buffer.begin(), buffer.end(), *this);
}
diff --git a/include/osmium/handler/node_locations_for_ways.hpp b/include/osmium/handler/node_locations_for_ways.hpp
index 61c6de2..a490f9e 100644
--- a/include/osmium/handler/node_locations_for_ways.hpp
+++ b/include/osmium/handler/node_locations_for_ways.hpp
@@ -165,7 +165,7 @@ namespace osmium {
}
}
if (error && !m_ignore_errors) {
- throw osmium::not_found{"location for one or more nodes not found in node location index"};
+ throw osmium::not_found("location for one or more nodes not found in node location index");
}
}
diff --git a/include/osmium/handler/object_relations.hpp b/include/osmium/handler/object_relations.hpp
index 5f1956d..279365d 100644
--- a/include/osmium/handler/object_relations.hpp
+++ b/include/osmium/handler/object_relations.hpp
@@ -46,8 +46,6 @@ namespace osmium {
namespace handler {
/**
- * This handler updates the indexes given to the constructor with
- * the relations between objects.
*
* Note: This handler will only work if either all object IDs are
* positive or all object IDs are negative.
diff --git a/include/osmium/index/bool_vector.hpp b/include/osmium/index/bool_vector.hpp
index 2ef80f9..e6e190e 100644
--- a/include/osmium/index/bool_vector.hpp
+++ b/include/osmium/index/bool_vector.hpp
@@ -33,15 +33,50 @@ DEALINGS IN THE SOFTWARE.
*/
-#include <osmium/index/id_set.hpp>
+#include <type_traits>
+#include <vector>
namespace osmium {
namespace index {
- /// @deprecated Use osmium::index::IdSet instead.
+ /**
+ * 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>
- using BoolVector = IdSet<T>;
+ class BoolVector {
+
+ static_assert(std::is_unsigned<T>::value, "Needs unsigned type");
+
+ std::vector<bool> m_bits;
+
+ public:
+
+ BoolVector() = default;
+
+ BoolVector(const BoolVector&) = default;
+ BoolVector(BoolVector&&) = default;
+ BoolVector& operator=(const BoolVector&) = default;
+ BoolVector& operator=(BoolVector&&) = default;
+
+ ~BoolVector() noexcept = default;
+
+ 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 BoolVector
} // namespace index
diff --git a/include/osmium/index/detail/vector_map.hpp b/include/osmium/index/detail/vector_map.hpp
index 9f4af1f..ac87c2f 100644
--- a/include/osmium/index/detail/vector_map.hpp
+++ b/include/osmium/index/detail/vector_map.hpp
@@ -85,11 +85,11 @@ namespace osmium {
try {
const TValue& value = m_vector.at(id);
if (value == osmium::index::empty_value<TValue>()) {
- throw osmium::not_found{id};
+ not_found_error(id);
}
return value;
} catch (const std::out_of_range&) {
- throw osmium::not_found{id};
+ not_found_error(id);
}
}
@@ -180,7 +180,7 @@ namespace osmium {
return a.first < b.first;
});
if (result == m_vector.end() || result->first != id) {
- throw osmium::not_found{id};
+ not_found_error(id);
} else {
return result->second;
}
diff --git a/include/osmium/index/id_set.hpp b/include/osmium/index/id_set.hpp
deleted file mode 100644
index 4a894a0..0000000
--- a/include/osmium/index/id_set.hpp
+++ /dev/null
@@ -1,431 +0,0 @@
-#ifndef OSMIUM_INDEX_ID_SET_HPP
-#define OSMIUM_INDEX_ID_SET_HPP
-
-/*
-
-This file is part of Osmium (http://osmcode.org/libosmium).
-
-Copyright 2013-2016 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 <algorithm>
-#include <cassert>
-#include <cstring>
-#include <memory>
-#include <type_traits>
-#include <unordered_set>
-#include <vector>
-
-#include <osmium/osm/item_type.hpp>
-#include <osmium/osm/types.hpp>
-
-namespace osmium {
-
- namespace index {
-
- /**
- * Virtual parent class for IdSets. Use one of the implementations
- * provided.
- */
- template <typename T>
- class IdSet {
-
- public:
-
- virtual ~IdSet() {
- }
-
- /**
- * Add the given Id to the set.
- */
- virtual void set(T id) = 0;
-
- /**
- * Is the Id in the set?
- */
- virtual bool get(T id) const noexcept = 0;
-
- /**
- * Is the set empty?
- */
- virtual bool empty() const = 0;
-
- /**
- * Clear the set.
- */
- virtual void clear() = 0;
-
- }; // class IdSet
-
- template <typename T>
- class IdSetDense;
-
- /**
- * Const_iterator for iterating over a IdSetDense.
- */
- template <typename T>
- class IdSetDenseIterator {
-
- const IdSetDense<T>* m_set;
- T m_value;
- T m_last;
-
- void next() noexcept {
- while (m_value != m_last && !m_set->get(m_value)) {
- const auto cid = IdSetDense<T>::chunk_id(m_value);
- assert(cid < m_set->m_data.size());
- if (!m_set->m_data[cid]) {
- m_value = (cid + 1) << (IdSetDense<T>::chunk_bits + 3);
- } else {
- const auto slot = m_set->m_data[cid][IdSetDense<T>::offset(m_value)];
- if (slot == 0) {
- m_value += 8;
- m_value &= ~0x7;
- } else {
- ++m_value;
- }
- }
- }
- }
-
- public:
-
- using iterator_category = std::forward_iterator_tag;
- using value_type = T;
- using pointer = value_type*;
- using reference = value_type&;
-
- IdSetDenseIterator(const IdSetDense<T>* set, T value, T last) noexcept :
- m_set(set),
- m_value(value),
- m_last(last) {
- next();
- }
-
- IdSetDenseIterator<T>& operator++() noexcept {
- if (m_value != m_last) {
- ++m_value;
- next();
- }
- return *this;
- }
-
- IdSetDenseIterator<T> operator++(int) noexcept {
- IdSetDenseIterator<T> tmp(*this);
- operator++();
- return tmp;
- }
-
- bool operator==(const IdSetDenseIterator<T>& rhs) const noexcept {
- return m_set == rhs.m_set && m_value == rhs.m_value;
- }
-
- bool operator!=(const IdSetDenseIterator<T>& rhs) const noexcept {
- return ! (*this == rhs);
- }
-
- T operator*() const noexcept {
- assert(m_value < m_last);
- return m_value;
- }
-
- }; // class IdSetDenseIterator
-
- /**
- * A set of Ids of the given type. Internal storage is in chunks of
- * arrays used as bit fields. Internally those chunks will be allocated
- * as needed, so it works relatively efficiently with both smaller
- * and larger Id sets. If it is not used, no memory is allocated at
- * all.
- */
- template <typename T>
- class IdSetDense : public IdSet<T> {
-
- static_assert(std::is_unsigned<T>::value, "Needs unsigned type");
- static_assert(sizeof(T) >= 4, "Needs at least 32bit type");
-
- friend class IdSetDenseIterator<T>;
-
- // This value is a compromise. For node Ids it could be bigger
- // which would mean less (but larger) memory allocations. For
- // relations Ids it could be smaller, because they would all fit
- // into a smaller allocation.
- constexpr static const size_t chunk_bits = 22;
- constexpr static const size_t chunk_size = 1 << chunk_bits;
-
- std::vector<std::unique_ptr<unsigned char[]>> m_data;
- size_t m_size = 0;
-
- static size_t chunk_id(T id) noexcept {
- return id >> (chunk_bits + 3);
- }
-
- static size_t offset(T id) noexcept {
- return (id >> 3) & ((1 << chunk_bits) - 1);
- }
-
- static unsigned char bitmask(T id) noexcept {
- return 1 << (id & 0x7);
- }
-
- T last() const noexcept {
- return m_data.size() * chunk_size * 8;
- }
-
- unsigned char& get_element(T id) {
- const auto cid = chunk_id(id);
- if (cid >= m_data.size()) {
- m_data.resize(cid + 1);
- }
-
- auto& chunk = m_data[cid];
- if (!chunk) {
- chunk.reset(new unsigned char[chunk_size]);
- ::memset(chunk.get(), 0, chunk_size);
- }
-
- return chunk[offset(id)];
- }
-
- public:
-
- using const_iterator = IdSetDenseIterator<T>;
-
- IdSetDense() = default;
-
- /**
- * Add the Id to the set if it is not already in there.
- *
- * @param id The Id to set.
- * @returns true if the Id was added, false if it was already set.
- */
- bool check_and_set(T id) {
- auto& element = get_element(id);
-
- if ((element & bitmask(id)) == 0) {
- element |= bitmask(id);
- ++m_size;
- return true;
- }
-
- return false;
- }
-
- /**
- * Add the given Id to the set.
- *
- * @param id The Id to set.
- */
- void set(T id) override final {
- (void)check_and_set(id);
- }
-
- /**
- * Remove the given Id from the set.
- *
- * @param id The Id to set.
- */
- void unset(T id) {
- auto& element = get_element(id);
-
- if ((element & bitmask(id)) != 0) {
- element &= ~bitmask(id);
- --m_size;
- }
- }
-
- /**
- * Is the Id in the set?
- *
- * @param id The Id to check.
- */
- bool get(T id) const noexcept override final {
- if (chunk_id(id) >= m_data.size()) {
- return false;
- }
- auto* r = m_data[chunk_id(id)].get();
- if (!r) {
- return false;
- }
- return (r[offset(id)] & bitmask(id)) != 0;
- }
-
- /**
- * Is the set empty?
- */
- bool empty() const noexcept override final {
- return m_size == 0;
- }
-
- /**
- * The number of Ids stored in the set.
- */
- size_t size() const noexcept {
- return m_size;
- }
-
- /**
- * Clear the set.
- */
- void clear() override final {
- m_data.clear();
- m_size = 0;
- }
-
- IdSetDenseIterator<T> begin() const {
- return IdSetDenseIterator<T>{this, 0, last()};
- }
-
- IdSetDenseIterator<T> end() const {
- return IdSetDenseIterator<T>{this, last(), last()};
- }
-
- }; // class IdSetDense
-
- /**
- * IdSet implementation for small Id sets. It writes the Ids
- * into a vector and uses linear search.
- */
- template <typename T>
- class IdSetSmall : public IdSet<T> {
-
- std::vector<T> m_data;
-
- public:
-
- /**
- * Add the given Id to the set.
- */
- void set(T id) override final {
- m_data.push_back(id);
- }
-
- /**
- * Is the Id in the set? Uses linear search.
- *
- * @param id The Id to check.
- */
- bool get(T id) const noexcept override final {
- const auto it = std::find(m_data.cbegin(), m_data.cend(), id);
- return it != m_data.cend();
- }
-
- /**
- * Is the Id in the set? Uses a binary search. For larger sets
- * this might be more efficient than calling get(), the set
- * must be sorted.
- *
- * @param id The Id to check.
- * @pre You must have called sort_unique() before calling this
- * or be sure there are no duplicates and the Ids have been
- * set in order.
- */
- bool get_binary_search(T id) const noexcept {
- return std::binary_search(m_data.cbegin(), m_data.cend(), id);
- }
-
- /**
- * Is the set empty?
- */
- bool empty() const noexcept override final {
- return m_data.empty();
- }
-
- /**
- * Clear the set.
- */
- void clear() override final {
- m_data.clear();
- }
-
- /**
- * Sort the internal vector and remove any duplicates. Call this
- * before using size(), get_binary_search() or using an iterator.
- */
- void sort_unique() {
- std::sort(m_data.begin(), m_data.end());
- const auto last = std::unique(m_data.begin(), m_data.end());
- m_data.erase(last, m_data.end());
-
- }
-
- /**
- * The number of Ids stored in the set.
- *
- * @pre You must have called sort_unique() before calling this
- * or be sure there are no duplicates.
- */
- size_t size() const noexcept {
- return m_data.size();
- }
-
- /// Iterator type. There is no non-const iterator.
- using const_iterator = typename std::vector<T>::const_iterator;
-
- const_iterator begin() const noexcept {
- return m_data.cbegin();
- }
-
- const_iterator end() const noexcept {
- return m_data.cend();
- }
-
- const_iterator cbegin() const noexcept {
- return m_data.cbegin();
- }
-
- const_iterator cend() const noexcept {
- return m_data.cend();
- }
-
- }; // class IdSetSmall
-
- template <template<typename> class IdSetType>
- class NWRIdSet {
-
- using id_set_type = IdSetType<osmium::unsigned_object_id_type>;
-
- id_set_type m_sets[3];
-
- public:
-
- id_set_type& operator()(osmium::item_type type) noexcept {
- return m_sets[osmium::item_type_to_nwr_index(type)];
- }
-
- const id_set_type& operator()(osmium::item_type type) const noexcept {
- return m_sets[osmium::item_type_to_nwr_index(type)];
- }
-
- }; // class NWRIdSet
-
- } // namespace index
-
-} // namespace osmium
-
-#endif // OSMIUM_INDEX_ID_SET_HPP
diff --git a/include/osmium/index/index.hpp b/include/osmium/index/index.hpp
index 65871f2..c3deead 100644
--- a/include/osmium/index/index.hpp
+++ b/include/osmium/index/index.hpp
@@ -35,6 +35,7 @@ DEALINGS IN THE SOFTWARE.
#include <cstddef>
#include <limits>
+#include <sstream>
#include <stdexcept>
#include <string>
@@ -56,10 +57,6 @@ namespace osmium {
std::runtime_error(what) {
}
- explicit not_found(uint64_t id) :
- std::runtime_error(std::string{"id "} + std::to_string(id) + " not found") {
- }
-
}; // struct not_found
/**
@@ -67,6 +64,13 @@ namespace osmium {
*/
namespace index {
+ template <typename TKey>
+ OSMIUM_NORETURN void not_found_error(TKey key) {
+ std::stringstream s;
+ s << "id " << key << " not found";
+ throw not_found(s.str());
+ }
+
/**
* Some of the index classes need an "empty" value that can
* never appear in real data. This function must return this
diff --git a/include/osmium/index/map.hpp b/include/osmium/index/map.hpp
index d26a4aa..1d2d5aa 100644
--- a/include/osmium/index/map.hpp
+++ b/include/osmium/index/map.hpp
@@ -48,18 +48,6 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
- struct map_factory_error : public std::runtime_error {
-
- explicit map_factory_error(const char* message) :
- std::runtime_error(message) {
- }
-
- explicit map_factory_error(const std::string& message) :
- std::runtime_error(message) {
- }
-
- }; // struct map_factory_error
-
namespace index {
/**
@@ -160,14 +148,14 @@ namespace osmium {
// default implementation is empty
}
- // This function can usually be const in derived classes,
+ // This function could usually be const in derived classes,
// but not always. It could, for instance, sort internal data.
// This is why it is not declared const here.
virtual void dump_as_list(const int /*fd*/) {
throw std::runtime_error("can't dump as list");
}
- // This function can usually be const in derived classes,
+ // This function could usually be const in derived classes,
// but not always. It could, for instance, sort internal data.
// This is why it is not declared const here.
virtual void dump_as_array(const int /*fd*/) {
@@ -200,6 +188,13 @@ namespace osmium {
MapFactory(MapFactory&&) = delete;
MapFactory& operator=(MapFactory&&) = delete;
+ OSMIUM_NORETURN static void error(const std::string& map_type_name) {
+ std::string error_message {"Support for map type '"};
+ error_message += map_type_name;
+ error_message += "' not compiled into this binary.";
+ throw std::runtime_error(error_message);
+ }
+
public:
static MapFactory<id_type, value_type>& instance() {
@@ -231,7 +226,7 @@ namespace osmium {
std::vector<std::string> config = osmium::split_string(config_string, ',');
if (config.empty()) {
- throw map_factory_error{"Need non-empty map type name"};
+ throw std::runtime_error("Need non-empty map type name.");
}
auto it = m_callbacks.find(config[0]);
@@ -239,7 +234,7 @@ namespace osmium {
return std::unique_ptr<map_type>((it->second)(config));
}
- throw map_factory_error{std::string{"Support for map type '"} + config[0] + "' not compiled into this binary"};
+ error(config[0]);
}
}; // class MapFactory
diff --git a/include/osmium/index/map/dummy.hpp b/include/osmium/index/map/dummy.hpp
index 529ad25..98d082b 100644
--- a/include/osmium/index/map/dummy.hpp
+++ b/include/osmium/index/map/dummy.hpp
@@ -63,7 +63,7 @@ namespace osmium {
}
const TValue get(const TId id) const final {
- throw osmium::not_found{id};
+ not_found_error(id);
}
size_t size() const final {
diff --git a/include/osmium/index/map/sparse_mem_map.hpp b/include/osmium/index/map/sparse_mem_map.hpp
index 43fea36..1e3c58c 100644
--- a/include/osmium/index/map/sparse_mem_map.hpp
+++ b/include/osmium/index/map/sparse_mem_map.hpp
@@ -79,7 +79,7 @@ namespace osmium {
const TValue get(const TId id) const final {
auto it = m_elements.find(id);
if (it == m_elements.end()) {
- throw osmium::not_found{id};
+ not_found_error(id);
}
return it->second;
}
diff --git a/include/osmium/index/map/sparse_mem_table.hpp b/include/osmium/index/map/sparse_mem_table.hpp
index 68f5797..241a64f 100644
--- a/include/osmium/index/map/sparse_mem_table.hpp
+++ b/include/osmium/index/map/sparse_mem_table.hpp
@@ -99,10 +99,10 @@ namespace osmium {
const TValue get(const TId id) const final {
if (id >= m_elements.size()) {
- throw osmium::not_found{id};
+ not_found_error(id);
}
if (m_elements[id] == osmium::index::empty_value<TValue>()) {
- throw osmium::not_found{id};
+ not_found_error(id);
}
return m_elements[id];
}
diff --git a/include/osmium/io/compression.hpp b/include/osmium/io/compression.hpp
index a38bba6..e7f93bd 100644
--- a/include/osmium/io/compression.hpp
+++ b/include/osmium/io/compression.hpp
@@ -145,11 +145,10 @@ namespace osmium {
private:
- using callbacks_type = std::tuple<create_compressor_type,
- create_decompressor_type_fd,
- create_decompressor_type_buffer>;
-
- using compression_map_type = std::map<const osmium::io::file_compression, callbacks_type>;
+ using compression_map_type = std::map<const osmium::io::file_compression,
+ std::tuple<create_compressor_type,
+ create_decompressor_type_fd,
+ create_decompressor_type_buffer>>;
compression_map_type m_callbacks;
@@ -161,17 +160,11 @@ namespace osmium {
CompressionFactory(CompressionFactory&&) = delete;
CompressionFactory& operator=(CompressionFactory&&) = delete;
- const callbacks_type& find_callbacks(osmium::io::file_compression compression) const {
- const auto it = m_callbacks.find(compression);
-
- if (it != m_callbacks.end()) {
- return it->second;
- }
-
- std::string error_message{"Support for compression '"};
+ OSMIUM_NORETURN void error(osmium::io::file_compression compression) {
+ std::string error_message {"Support for compression '"};
error_message += as_string(compression);
- error_message += "' not compiled into this binary";
- throw unsupported_file_format_error{error_message};
+ error_message += "' not compiled into this binary.";
+ throw unsupported_file_format_error(error_message);
}
public:
@@ -196,21 +189,36 @@ namespace osmium {
}
template <typename... TArgs>
- std::unique_ptr<osmium::io::Compressor> create_compressor(osmium::io::file_compression compression, TArgs&&... args) const {
- const auto callbacks = find_callbacks(compression);
- return std::unique_ptr<osmium::io::Compressor>(std::get<0>(callbacks)(std::forward<TArgs>(args)...));
+ std::unique_ptr<osmium::io::Compressor> create_compressor(osmium::io::file_compression compression, TArgs&&... args) {
+ auto it = m_callbacks.find(compression);
+
+ if (it != m_callbacks.end()) {
+ return std::unique_ptr<osmium::io::Compressor>(std::get<0>(it->second)(std::forward<TArgs>(args)...));
+ }
+
+ error(compression);
}
- std::unique_ptr<osmium::io::Decompressor> create_decompressor(osmium::io::file_compression compression, int fd) const {
- const auto callbacks = find_callbacks(compression);
- auto p = std::unique_ptr<osmium::io::Decompressor>(std::get<1>(callbacks)(fd));
- p->set_file_size(osmium::util::file_size(fd));
- return p;
+ std::unique_ptr<osmium::io::Decompressor> create_decompressor(osmium::io::file_compression compression, int fd) {
+ auto it = m_callbacks.find(compression);
+
+ if (it != m_callbacks.end()) {
+ auto p = std::unique_ptr<osmium::io::Decompressor>(std::get<1>(it->second)(fd));
+ p->set_file_size(osmium::util::file_size(fd));
+ return p;
+ }
+
+ error(compression);
}
- std::unique_ptr<osmium::io::Decompressor> create_decompressor(osmium::io::file_compression compression, const char* buffer, size_t size) const {
- const auto callbacks = find_callbacks(compression);
- return std::unique_ptr<osmium::io::Decompressor>(std::get<2>(callbacks)(buffer, size));
+ std::unique_ptr<osmium::io::Decompressor> create_decompressor(osmium::io::file_compression compression, const char* buffer, size_t size) {
+ auto it = m_callbacks.find(compression);
+
+ if (it != m_callbacks.end()) {
+ return std::unique_ptr<osmium::io::Decompressor>(std::get<2>(it->second)(buffer, size));
+ }
+
+ error(compression);
}
}; // class CompressionFactory
diff --git a/include/osmium/io/detail/input_format.hpp b/include/osmium/io/detail/input_format.hpp
index 67b05a8..98081e3 100644
--- a/include/osmium/io/detail/input_format.hpp
+++ b/include/osmium/io/detail/input_format.hpp
@@ -55,17 +55,12 @@ namespace osmium {
namespace detail {
- struct reader_options {
- osmium::osm_entity_bits::type read_which_entities = osm_entity_bits::all;
- osmium::io::read_meta read_metadata = read_meta::yes;
- };
-
class Parser {
future_buffer_queue_type& m_output_queue;
std::promise<osmium::io::Header>& m_header_promise;
queue_wrapper<std::string> m_input_queue;
- reader_options m_options;
+ osmium::osm_entity_bits::type m_read_types;
bool m_header_is_done;
protected:
@@ -78,15 +73,11 @@ namespace osmium {
return m_input_queue.has_reached_end_of_data();
}
- osmium::osm_entity_bits::type read_types() const noexcept {
- return m_options.read_which_entities;
- }
-
- osmium::io::read_meta read_metadata() const noexcept {
- return m_options.read_metadata;
+ osmium::osm_entity_bits::type read_types() const {
+ return m_read_types;
}
- bool header_is_done() const noexcept {
+ bool header_is_done() const {
return m_header_is_done;
}
@@ -120,11 +111,11 @@ namespace osmium {
Parser(future_string_queue_type& input_queue,
future_buffer_queue_type& output_queue,
std::promise<osmium::io::Header>& header_promise,
- osmium::io::detail::reader_options options) :
+ osmium::osm_entity_bits::type read_types) :
m_output_queue(output_queue),
m_header_promise(header_promise),
m_input_queue(input_queue),
- m_options(options),
+ m_read_types(read_types),
m_header_is_done(false) {
}
@@ -166,7 +157,7 @@ namespace osmium {
using create_parser_type = std::function<std::unique_ptr<Parser>(future_string_queue_type&,
future_buffer_queue_type&,
std::promise<osmium::io::Header>& header_promise,
- osmium::io::detail::reader_options options)>;
+ osmium::osm_entity_bits::type read_which_entities)>;
private:
diff --git a/include/osmium/io/detail/o5m_input_format.hpp b/include/osmium/io/detail/o5m_input_format.hpp
index de4595e..d642879 100644
--- a/include/osmium/io/detail/o5m_input_format.hpp
+++ b/include/osmium/io/detail/o5m_input_format.hpp
@@ -80,7 +80,7 @@ namespace osmium {
struct o5m_error : public io_error {
explicit o5m_error(const char* what) :
- io_error(std::string{"o5m format error: "} + what) {
+ io_error(std::string("o5m format error: ") + what) {
}
}; // struct o5m_error
@@ -135,7 +135,7 @@ namespace osmium {
const char* get(uint64_t index) const {
if (m_table.empty() || index == 0 || index > number_of_entries) {
- throw o5m_error{"reference to non-existing string in table"};
+ throw o5m_error("reference to non-existing string in table");
}
auto entry = (current_entry + number_of_entries - index) % number_of_entries;
return &m_table[entry * entry_size];
@@ -191,7 +191,7 @@ namespace osmium {
static const unsigned char header_magic[] = { 0xff, 0xe0, 0x04, 'o', '5' };
if (std::strncmp(reinterpret_cast<const char*>(header_magic), m_data, sizeof(header_magic))) {
- throw o5m_error{"wrong header magic"};
+ throw o5m_error("wrong header magic");
}
m_data += sizeof(header_magic);
@@ -203,7 +203,7 @@ namespace osmium {
} else if (*m_data == 'c') { // o5c change file
m_header.set_has_multiple_object_versions(true);
} else {
- throw o5m_error{"wrong header magic"};
+ throw o5m_error("wrong header magic");
}
m_data++;
@@ -211,7 +211,7 @@ namespace osmium {
void check_file_format_version() {
if (*m_data != '2') {
- throw o5m_error{"wrong header magic"};
+ throw o5m_error("wrong header magic");
}
m_data++;
@@ -219,7 +219,7 @@ namespace osmium {
void decode_header() {
if (! ensure_bytes_available(7)) { // overall length of header
- throw o5m_error{"file too short (incomplete header info)"};
+ throw o5m_error("file too short (incomplete header info)");
}
check_header_magic();
@@ -260,7 +260,7 @@ namespace osmium {
if (**dataptr == 0x00) { // get inline string
(*dataptr)++;
if (*dataptr == end) {
- throw o5m_error{"string format error"};
+ throw o5m_error("string format error");
}
return *dataptr;
} else { // get from reference table
@@ -277,7 +277,7 @@ namespace osmium {
auto uid = protozero::decode_varint(&data, end);
if (data == end) {
- throw o5m_error{"missing user name"};
+ throw o5m_error("missing user name");
}
const char* user = ++data;
@@ -290,7 +290,7 @@ namespace osmium {
while (*data++) {
if (data == end) {
- throw o5m_error{"no null byte in user name"};
+ throw o5m_error("no null byte in user name");
}
}
@@ -302,24 +302,24 @@ namespace osmium {
return std::make_pair(static_cast_with_assert<osmium::user_id_type>(uid), user);
}
- void decode_tags(osmium::builder::Builder& parent, const char** dataptr, const char* const end) {
- osmium::builder::TagListBuilder builder{parent};
+ void decode_tags(osmium::builder::Builder* builder, const char** dataptr, const char* const end) {
+ osmium::builder::TagListBuilder tl_builder(m_buffer, builder);
- while (*dataptr != end) {
+ while(*dataptr != end) {
bool update_pointer = (**dataptr == 0x00);
const char* data = decode_string(dataptr, end);
const char* start = data;
while (*data++) {
if (data == end) {
- throw o5m_error{"no null byte in tag key"};
+ throw o5m_error("no null byte in tag key");
}
}
const char* value = data;
while (*data++) {
if (data == end) {
- throw o5m_error{"no null byte in tag value"};
+ throw o5m_error("no null byte in tag value");
}
}
@@ -328,7 +328,7 @@ namespace osmium {
*dataptr = data;
}
- builder.add_tag(start, value);
+ tl_builder.add_tag(start, value);
}
}
@@ -357,46 +357,50 @@ namespace osmium {
}
void decode_node(const char* data, const char* const end) {
- osmium::builder::NodeBuilder builder{m_buffer};
+ osmium::builder::NodeBuilder builder(m_buffer);
+ osmium::Node& node = builder.object();
- builder.set_id(m_delta_id.update(zvarint(&data, end)));
+ node.set_id(m_delta_id.update(zvarint(&data, end)));
- builder.set_user(decode_info(builder.object(), &data, end));
+ builder.add_user(decode_info(node, &data, end));
if (data == end) {
// no location, object is deleted
- builder.set_visible(false);
- builder.set_location(osmium::Location{});
+ builder.object().set_visible(false);
+ builder.object().set_location(osmium::Location{});
} else {
auto lon = m_delta_lon.update(zvarint(&data, end));
auto lat = m_delta_lat.update(zvarint(&data, end));
- builder.set_location(osmium::Location{lon, lat});
+ builder.object().set_location(osmium::Location{lon, lat});
if (data != end) {
- decode_tags(builder, &data, end);
+ decode_tags(&builder, &data, end);
}
}
+
+ m_buffer.commit();
}
void decode_way(const char* data, const char* const end) {
- osmium::builder::WayBuilder builder{m_buffer};
+ osmium::builder::WayBuilder builder(m_buffer);
+ osmium::Way& way = builder.object();
- builder.set_id(m_delta_id.update(zvarint(&data, end)));
+ way.set_id(m_delta_id.update(zvarint(&data, end)));
- builder.set_user(decode_info(builder.object(), &data, end));
+ builder.add_user(decode_info(way, &data, end));
if (data == end) {
// no reference section, object is deleted
- builder.set_visible(false);
+ builder.object().set_visible(false);
} else {
auto reference_section_length = protozero::decode_varint(&data, end);
if (reference_section_length > 0) {
const char* const end_refs = data + reference_section_length;
if (end_refs > end) {
- throw o5m_error{"way nodes ref section too long"};
+ throw o5m_error("way nodes ref section too long");
}
- osmium::builder::WayNodeListBuilder wn_builder{builder};
+ osmium::builder::WayNodeListBuilder wn_builder(m_buffer, &builder);
while (data < end_refs) {
wn_builder.add_node_ref(m_delta_way_node_id.update(zvarint(&data, end)));
@@ -404,14 +408,16 @@ namespace osmium {
}
if (data != end) {
- decode_tags(builder, &data, end);
+ decode_tags(&builder, &data, end);
}
}
+
+ m_buffer.commit();
}
osmium::item_type decode_member_type(char c) {
if (c < '0' || c > '2') {
- throw o5m_error{"unknown member type"};
+ throw o5m_error("unknown member type");
}
return osmium::nwr_index_to_item_type(c - '0');
}
@@ -423,13 +429,13 @@ namespace osmium {
auto member_type = decode_member_type(*data++);
if (data == end) {
- throw o5m_error{"missing role"};
+ throw o5m_error("missing role");
}
const char* role = data;
while (*data++) {
if (data == end) {
- throw o5m_error{"no null byte in role"};
+ throw o5m_error("no null byte in role");
}
}
@@ -442,29 +448,30 @@ namespace osmium {
}
void decode_relation(const char* data, const char* const end) {
- osmium::builder::RelationBuilder builder{m_buffer};
+ osmium::builder::RelationBuilder builder(m_buffer);
+ osmium::Relation& relation = builder.object();
- builder.set_id(m_delta_id.update(zvarint(&data, end)));
+ relation.set_id(m_delta_id.update(zvarint(&data, end)));
- builder.set_user(decode_info(builder.object(), &data, end));
+ builder.add_user(decode_info(relation, &data, end));
if (data == end) {
// no reference section, object is deleted
- builder.set_visible(false);
+ builder.object().set_visible(false);
} else {
auto reference_section_length = protozero::decode_varint(&data, end);
if (reference_section_length > 0) {
const char* const end_refs = data + reference_section_length;
if (end_refs > end) {
- throw o5m_error{"relation format error"};
+ throw o5m_error("relation format error");
}
- osmium::builder::RelationMemberListBuilder rml_builder{builder};
+ osmium::builder::RelationMemberListBuilder rml_builder(m_buffer, &builder);
while (data < end_refs) {
auto delta_id = zvarint(&data, end);
if (data == end) {
- throw o5m_error{"relation member format error"};
+ throw o5m_error("relation member format error");
}
auto type_role = decode_role(&data, end);
auto i = osmium::item_type_to_nwr_index(type_role.first);
@@ -474,9 +481,11 @@ namespace osmium {
}
if (data != end) {
- decode_tags(builder, &data, end);
+ decode_tags(&builder, &data, end);
}
}
+
+ m_buffer.commit();
}
void decode_bbox(const char* data, const char* const end) {
@@ -528,11 +537,11 @@ namespace osmium {
try {
length = protozero::decode_varint(&m_data, m_end);
} catch (const protozero::end_of_buffer_exception&) {
- throw o5m_error{"premature end of file"};
+ throw o5m_error("premature end of file");
}
if (! ensure_bytes_available(length)) {
- throw o5m_error{"premature end of file"};
+ throw o5m_error("premature end of file");
}
switch (ds_type) {
@@ -540,21 +549,18 @@ namespace osmium {
mark_header_as_done();
if (read_types() & osmium::osm_entity_bits::node) {
decode_node(m_data, m_data + length);
- m_buffer.commit();
}
break;
case dataset_type::way:
mark_header_as_done();
if (read_types() & osmium::osm_entity_bits::way) {
decode_way(m_data, m_data + length);
- m_buffer.commit();
}
break;
case dataset_type::relation:
mark_header_as_done();
if (read_types() & osmium::osm_entity_bits::relation) {
decode_relation(m_data, m_data + length);
- m_buffer.commit();
}
break;
case dataset_type::bounding_box:
@@ -592,8 +598,8 @@ namespace osmium {
O5mParser(future_string_queue_type& input_queue,
future_buffer_queue_type& output_queue,
std::promise<osmium::io::Header>& header_promise,
- osmium::io::detail::reader_options options) :
- Parser(input_queue, output_queue, header_promise, options),
+ osmium::osm_entity_bits::type read_types) :
+ Parser(input_queue, output_queue, header_promise, read_types),
m_header(),
m_buffer(buffer_size),
m_input(),
@@ -619,8 +625,8 @@ namespace osmium {
[](future_string_queue_type& input_queue,
future_buffer_queue_type& output_queue,
std::promise<osmium::io::Header>& header_promise,
- osmium::io::detail::reader_options options) {
- return std::unique_ptr<Parser>(new O5mParser(input_queue, output_queue, header_promise, options));
+ osmium::osm_entity_bits::type read_which_entities) {
+ return std::unique_ptr<Parser>(new O5mParser(input_queue, output_queue, header_promise, read_which_entities));
});
// dummy function to silence the unused variable warning from above
diff --git a/include/osmium/io/detail/opl_input_format.hpp b/include/osmium/io/detail/opl_input_format.hpp
index 1bd8b07..15a31f3 100644
--- a/include/osmium/io/detail/opl_input_format.hpp
+++ b/include/osmium/io/detail/opl_input_format.hpp
@@ -82,8 +82,8 @@ namespace osmium {
OPLParser(future_string_queue_type& input_queue,
future_buffer_queue_type& output_queue,
std::promise<osmium::io::Header>& header_promise,
- osmium::io::detail::reader_options options) :
- Parser(input_queue, output_queue, header_promise, options) {
+ osmium::osm_entity_bits::type read_types) :
+ Parser(input_queue, output_queue, header_promise, read_types) {
set_header_value(osmium::io::Header{});
}
@@ -137,8 +137,8 @@ namespace osmium {
[](future_string_queue_type& input_queue,
future_buffer_queue_type& output_queue,
std::promise<osmium::io::Header>& header_promise,
- osmium::io::detail::reader_options options) {
- return std::unique_ptr<Parser>(new OPLParser(input_queue, output_queue, header_promise, options));
+ osmium::osm_entity_bits::type read_which_entities) {
+ return std::unique_ptr<Parser>(new OPLParser(input_queue, output_queue, header_promise, read_which_entities));
});
// dummy function to silence the unused variable warning from above
diff --git a/include/osmium/io/detail/opl_parser_functions.hpp b/include/osmium/io/detail/opl_parser_functions.hpp
index ee35b36..97c5927 100644
--- a/include/osmium/io/detail/opl_parser_functions.hpp
+++ b/include/osmium/io/detail/opl_parser_functions.hpp
@@ -365,8 +365,9 @@ namespace osmium {
inline void opl_parse_node(const char** data, osmium::memory::Buffer& buffer) {
osmium::builder::NodeBuilder builder{buffer};
+ osmium::Node& node = builder.object();
- builder.set_id(opl_parse_id(data));
+ node.set_id(opl_parse_id(data));
const char* tags_begin = nullptr;
@@ -381,19 +382,19 @@ namespace osmium {
++(*data);
switch (c) {
case 'v':
- builder.set_version(opl_parse_version(data));
+ node.set_version(opl_parse_version(data));
break;
case 'd':
- builder.set_visible(opl_parse_visible(data));
+ node.set_visible(opl_parse_visible(data));
break;
case 'c':
- builder.set_changeset(opl_parse_changeset_id(data));
+ node.set_changeset(opl_parse_changeset_id(data));
break;
case 't':
- builder.set_timestamp(opl_parse_timestamp(data));
+ node.set_timestamp(opl_parse_timestamp(data));
break;
case 'i':
- builder.set_uid(opl_parse_uid(data));
+ node.set_uid(opl_parse_uid(data));
break;
case 'u':
opl_parse_string(data, user);
@@ -421,20 +422,23 @@ namespace osmium {
}
if (location.valid()) {
- builder.set_location(location);
+ node.set_location(location);
}
- builder.set_user(user);
+ builder.add_user(user);
if (tags_begin) {
opl_parse_tags(tags_begin, buffer, &builder);
}
+
+ buffer.commit();
}
inline void opl_parse_way(const char** data, osmium::memory::Buffer& buffer) {
osmium::builder::WayBuilder builder{buffer};
+ osmium::Way& way = builder.object();
- builder.set_id(opl_parse_id(data));
+ way.set_id(opl_parse_id(data));
const char* tags_begin = nullptr;
@@ -451,19 +455,19 @@ namespace osmium {
++(*data);
switch (c) {
case 'v':
- builder.set_version(opl_parse_version(data));
+ way.set_version(opl_parse_version(data));
break;
case 'd':
- builder.set_visible(opl_parse_visible(data));
+ way.set_visible(opl_parse_visible(data));
break;
case 'c':
- builder.set_changeset(opl_parse_changeset_id(data));
+ way.set_changeset(opl_parse_changeset_id(data));
break;
case 't':
- builder.set_timestamp(opl_parse_timestamp(data));
+ way.set_timestamp(opl_parse_timestamp(data));
break;
case 'i':
- builder.set_uid(opl_parse_uid(data));
+ way.set_uid(opl_parse_uid(data));
break;
case 'u':
opl_parse_string(data, user);
@@ -484,13 +488,15 @@ namespace osmium {
}
}
- builder.set_user(user);
+ builder.add_user(user);
if (tags_begin) {
opl_parse_tags(tags_begin, buffer, &builder);
}
opl_parse_way_nodes(nodes_begin, nodes_end, buffer, &builder);
+
+ buffer.commit();
}
inline void opl_parse_relation_members(const char* s, const char* e, osmium::memory::Buffer& buffer, osmium::builder::RelationBuilder* parent_builder = nullptr) {
@@ -530,8 +536,9 @@ namespace osmium {
inline void opl_parse_relation(const char** data, osmium::memory::Buffer& buffer) {
osmium::builder::RelationBuilder builder{buffer};
+ osmium::Relation& relation = builder.object();
- builder.set_id(opl_parse_id(data));
+ relation.set_id(opl_parse_id(data));
const char* tags_begin = nullptr;
@@ -548,19 +555,19 @@ namespace osmium {
++(*data);
switch (c) {
case 'v':
- builder.set_version(opl_parse_version(data));
+ relation.set_version(opl_parse_version(data));
break;
case 'd':
- builder.set_visible(opl_parse_visible(data));
+ relation.set_visible(opl_parse_visible(data));
break;
case 'c':
- builder.set_changeset(opl_parse_changeset_id(data));
+ relation.set_changeset(opl_parse_changeset_id(data));
break;
case 't':
- builder.set_timestamp(opl_parse_timestamp(data));
+ relation.set_timestamp(opl_parse_timestamp(data));
break;
case 'i':
- builder.set_uid(opl_parse_uid(data));
+ relation.set_uid(opl_parse_uid(data));
break;
case 'u':
opl_parse_string(data, user);
@@ -581,7 +588,7 @@ namespace osmium {
}
}
- builder.set_user(user);
+ builder.add_user(user);
if (tags_begin) {
opl_parse_tags(tags_begin, buffer, &builder);
@@ -590,12 +597,15 @@ namespace osmium {
if (members_begin != members_end) {
opl_parse_relation_members(members_begin, members_end, buffer, &builder);
}
+
+ buffer.commit();
}
inline void opl_parse_changeset(const char** data, osmium::memory::Buffer& buffer) {
osmium::builder::ChangesetBuilder builder{buffer};
+ osmium::Changeset& changeset = builder.object();
- builder.set_id(opl_parse_changeset_id(data));
+ changeset.set_id(opl_parse_changeset_id(data));
const char* tags_begin = nullptr;
@@ -611,19 +621,19 @@ namespace osmium {
++(*data);
switch (c) {
case 'k':
- builder.set_num_changes(opl_parse_int<osmium::num_changes_type>(data));
+ changeset.set_num_changes(opl_parse_int<osmium::num_changes_type>(data));
break;
case 's':
- builder.set_created_at(opl_parse_timestamp(data));
+ changeset.set_created_at(opl_parse_timestamp(data));
break;
case 'e':
- builder.set_closed_at(opl_parse_timestamp(data));
+ changeset.set_closed_at(opl_parse_timestamp(data));
break;
case 'd':
- builder.set_num_comments(opl_parse_int<osmium::num_comments_type>(data));
+ changeset.set_num_comments(opl_parse_int<osmium::num_comments_type>(data));
break;
case 'i':
- builder.set_uid(opl_parse_uid(data));
+ changeset.set_uid(opl_parse_uid(data));
break;
case 'u':
opl_parse_string(data, user);
@@ -662,17 +672,17 @@ namespace osmium {
}
if (location1.valid() && location2.valid()) {
- osmium::Box box;
- box.extend(location1);
- box.extend(location2);
- builder.set_bounds(box);
+ changeset.bounds().extend(location1);
+ changeset.bounds().extend(location2);
}
- builder.set_user(user);
+ builder.add_user(user);
if (tags_begin) {
opl_parse_tags(tags_begin, buffer, &builder);
}
+
+ buffer.commit();
}
inline bool opl_parse_line(uint64_t line_count,
@@ -692,7 +702,6 @@ namespace osmium {
if (read_types & osmium::osm_entity_bits::node) {
++data;
opl_parse_node(&data, buffer);
- buffer.commit();
return true;
}
break;
@@ -700,7 +709,6 @@ namespace osmium {
if (read_types & osmium::osm_entity_bits::way) {
++data;
opl_parse_way(&data, buffer);
- buffer.commit();
return true;
}
break;
@@ -708,7 +716,6 @@ namespace osmium {
if (read_types & osmium::osm_entity_bits::relation) {
++data;
opl_parse_relation(&data, buffer);
- buffer.commit();
return true;
}
break;
@@ -716,7 +723,6 @@ namespace osmium {
if (read_types & osmium::osm_entity_bits::changeset) {
++data;
opl_parse_changeset(&data, buffer);
- buffer.commit();
return true;
}
break;
diff --git a/include/osmium/io/detail/pbf_decoder.hpp b/include/osmium/io/detail/pbf_decoder.hpp
index 5164ce3..5df191d 100644
--- a/include/osmium/io/detail/pbf_decoder.hpp
+++ b/include/osmium/io/detail/pbf_decoder.hpp
@@ -50,7 +50,6 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/io/detail/pbf.hpp> // IWYU pragma: export
#include <osmium/io/detail/protobuf_tags.hpp>
#include <osmium/io/detail/zlib.hpp>
-#include <osmium/io/file_format.hpp>
#include <osmium/io/header.hpp>
#include <osmium/memory/buffer.hpp>
#include <osmium/osm/box.hpp>
@@ -95,8 +94,6 @@ namespace osmium {
osmium::memory::Buffer m_buffer { initial_buffer_size };
- osmium::io::read_meta m_read_metadata;
-
void decode_stringtable(const data_view& data) {
if (!m_stringtable.empty()) {
throw osmium::pbf_error("more than one stringtable in pbf file");
@@ -146,19 +143,13 @@ namespace osmium {
case OSMFormat::PrimitiveGroup::repeated_Node_nodes:
if (m_read_types & osmium::osm_entity_bits::node) {
decode_node(pbf_primitive_group.get_view());
- m_buffer.commit();
} else {
pbf_primitive_group.skip();
}
break;
case OSMFormat::PrimitiveGroup::optional_DenseNodes_dense:
if (m_read_types & osmium::osm_entity_bits::node) {
- if (m_read_metadata == osmium::io::read_meta::yes) {
- decode_dense_nodes(pbf_primitive_group.get_view());
- } else {
- decode_dense_nodes_without_metadata(pbf_primitive_group.get_view());
- }
- m_buffer.commit();
+ decode_dense_nodes(pbf_primitive_group.get_view());
} else {
pbf_primitive_group.skip();
}
@@ -166,7 +157,6 @@ namespace osmium {
case OSMFormat::PrimitiveGroup::repeated_Way_ways:
if (m_read_types & osmium::osm_entity_bits::way) {
decode_way(pbf_primitive_group.get_view());
- m_buffer.commit();
} else {
pbf_primitive_group.skip();
}
@@ -174,7 +164,6 @@ namespace osmium {
case OSMFormat::PrimitiveGroup::repeated_Relation_relations:
if (m_read_types & osmium::osm_entity_bits::relation) {
decode_relation(pbf_primitive_group.get_view());
- m_buffer.commit();
} else {
pbf_primitive_group.skip();
}
@@ -232,9 +221,9 @@ namespace osmium {
using kv_type = protozero::iterator_range<protozero::pbf_reader::const_uint32_iterator>;
- void build_tag_list(osmium::builder::Builder& parent, const kv_type& keys, const kv_type& vals) {
+ void build_tag_list(osmium::builder::Builder& builder, const kv_type& keys, const kv_type& vals) {
if (!keys.empty()) {
- osmium::builder::TagListBuilder builder{parent};
+ osmium::builder::TagListBuilder tl_builder(m_buffer, &builder);
auto kit = keys.begin();
auto vit = vals.begin();
while (kit != keys.end()) {
@@ -244,7 +233,7 @@ namespace osmium {
}
const auto& k = m_stringtable.at(*kit++);
const auto& v = m_stringtable.at(*vit++);
- builder.add_tag(k.first, k.second, v.first, v.second);
+ tl_builder.add_tag(k.first, k.second, v.first, v.second);
}
}
}
@@ -254,7 +243,7 @@ namespace osmium {
}
void decode_node(const data_view& data) {
- osmium::builder::NodeBuilder builder{m_buffer};
+ osmium::builder::NodeBuilder builder(m_buffer);
osmium::Node& node = builder.object();
kv_type keys;
@@ -277,11 +266,7 @@ namespace osmium {
vals = pbf_node.get_packed_uint32();
break;
case OSMFormat::Node::optional_Info_info:
- if (m_read_metadata == osmium::io::read_meta::yes) {
- user = decode_info(pbf_node.get_view(), builder.object());
- } else {
- pbf_node.skip();
- }
+ user = decode_info(pbf_node.get_view(), builder.object());
break;
case OSMFormat::Node::required_sint64_lat:
lat = pbf_node.get_sint64();
@@ -305,13 +290,15 @@ namespace osmium {
));
}
- builder.set_user(user.first, user.second);
+ builder.add_user(user.first, user.second);
build_tag_list(builder, keys, vals);
+
+ m_buffer.commit();
}
void decode_way(const data_view& data) {
- osmium::builder::WayBuilder builder{m_buffer};
+ osmium::builder::WayBuilder builder(m_buffer);
kv_type keys;
kv_type vals;
@@ -334,11 +321,7 @@ namespace osmium {
vals = pbf_way.get_packed_uint32();
break;
case OSMFormat::Way::optional_Info_info:
- if (m_read_metadata == osmium::io::read_meta::yes) {
- user = decode_info(pbf_way.get_view(), builder.object());
- } else {
- pbf_way.skip();
- }
+ user = decode_info(pbf_way.get_view(), builder.object());
break;
case OSMFormat::Way::packed_sint64_refs:
refs = pbf_way.get_packed_sint64();
@@ -354,10 +337,10 @@ namespace osmium {
}
}
- builder.set_user(user.first, user.second);
+ builder.add_user(user.first, user.second);
if (!refs.empty()) {
- osmium::builder::WayNodeListBuilder wnl_builder{builder};
+ osmium::builder::WayNodeListBuilder wnl_builder(m_buffer, &builder);
osmium::util::DeltaDecode<int64_t> ref;
if (lats.empty()) {
for (const auto& ref_value : refs) {
@@ -380,10 +363,12 @@ namespace osmium {
}
build_tag_list(builder, keys, vals);
+
+ m_buffer.commit();
}
void decode_relation(const data_view& data) {
- osmium::builder::RelationBuilder builder{m_buffer};
+ osmium::builder::RelationBuilder builder(m_buffer);
kv_type keys;
kv_type vals;
@@ -406,11 +391,7 @@ namespace osmium {
vals = pbf_relation.get_packed_uint32();
break;
case OSMFormat::Relation::optional_Info_info:
- if (m_read_metadata == osmium::io::read_meta::yes) {
- user = decode_info(pbf_relation.get_view(), builder.object());
- } else {
- pbf_relation.skip();
- }
+ user = decode_info(pbf_relation.get_view(), builder.object());
break;
case OSMFormat::Relation::packed_int32_roles_sid:
roles = pbf_relation.get_packed_int32();
@@ -426,10 +407,10 @@ namespace osmium {
}
}
- builder.set_user(user.first, user.second);
+ builder.add_user(user.first, user.second);
if (!refs.empty()) {
- osmium::builder::RelationMemberListBuilder rml_builder{builder};
+ osmium::builder::RelationMemberListBuilder rml_builder(m_buffer, &builder);
osmium::util::DeltaDecode<int64_t> ref;
while (!roles.empty() && !refs.empty() && !types.empty()) {
const auto& r = m_stringtable.at(roles.front());
@@ -450,84 +431,8 @@ namespace osmium {
}
build_tag_list(builder, keys, vals);
- }
-
- void build_tag_list_from_dense_nodes(osmium::builder::NodeBuilder& builder, protozero::pbf_reader::const_int32_iterator& it, protozero::pbf_reader::const_int32_iterator last) {
- osmium::builder::TagListBuilder tl_builder{builder};
- while (it != last && *it != 0) {
- const auto& k = m_stringtable.at(*it++);
- if (it == last) {
- throw osmium::pbf_error("PBF format error"); // this is against the spec, keys/vals must come in pairs
- }
- const auto& v = m_stringtable.at(*it++);
- tl_builder.add_tag(k.first, k.second, v.first, v.second);
- }
-
- if (it != last) {
- ++it;
- }
- }
-
- void decode_dense_nodes_without_metadata(const data_view& data) {
- protozero::iterator_range<protozero::pbf_reader::const_sint64_iterator> ids;
- protozero::iterator_range<protozero::pbf_reader::const_sint64_iterator> lats;
- protozero::iterator_range<protozero::pbf_reader::const_sint64_iterator> lons;
-
- protozero::iterator_range<protozero::pbf_reader::const_int32_iterator> tags;
-
- protozero::pbf_message<OSMFormat::DenseNodes> pbf_dense_nodes(data);
- while (pbf_dense_nodes.next()) {
- switch (pbf_dense_nodes.tag()) {
- case OSMFormat::DenseNodes::packed_sint64_id:
- ids = pbf_dense_nodes.get_packed_sint64();
- break;
- case OSMFormat::DenseNodes::packed_sint64_lat:
- lats = pbf_dense_nodes.get_packed_sint64();
- break;
- case OSMFormat::DenseNodes::packed_sint64_lon:
- lons = pbf_dense_nodes.get_packed_sint64();
- break;
- case OSMFormat::DenseNodes::packed_int32_keys_vals:
- tags = pbf_dense_nodes.get_packed_int32();
- break;
- default:
- pbf_dense_nodes.skip();
- }
- }
-
- osmium::util::DeltaDecode<int64_t> dense_id;
- osmium::util::DeltaDecode<int64_t> dense_latitude;
- osmium::util::DeltaDecode<int64_t> dense_longitude;
-
- auto tag_it = tags.begin();
-
- while (!ids.empty()) {
- if (lons.empty() ||
- lats.empty()) {
- // this is against the spec, must have same number of elements
- throw osmium::pbf_error("PBF format error");
- }
-
- osmium::builder::NodeBuilder builder{m_buffer};
- osmium::Node& node = builder.object();
-
- node.set_id(dense_id.update(ids.front()));
- ids.drop_front();
-
- const auto lon = dense_longitude.update(lons.front());
- lons.drop_front();
- const auto lat = dense_latitude.update(lats.front());
- lats.drop_front();
- builder.object().set_location(osmium::Location(
- convert_pbf_coordinate(lon),
- convert_pbf_coordinate(lat)
- ));
-
- if (tag_it != tags.end()) {
- build_tag_list_from_dense_nodes(builder, tag_it, tags.end());
- }
- }
+ m_buffer.commit();
}
void decode_dense_nodes(const data_view& data) {
@@ -617,7 +522,7 @@ namespace osmium {
bool visible = true;
- osmium::builder::NodeBuilder builder{m_buffer};
+ osmium::builder::NodeBuilder builder(m_buffer);
osmium::Node& node = builder.object();
node.set_id(dense_id.update(ids.front()));
@@ -664,7 +569,9 @@ namespace osmium {
const auto& u = m_stringtable.at(dense_user_sid.update(user_sids.front()));
user_sids.drop_front();
- builder.set_user(u.first, u.second);
+ builder.add_user(u.first, u.second);
+ } else {
+ builder.add_user("");
}
// even if the node isn't visible, there's still a record
@@ -681,18 +588,31 @@ namespace osmium {
}
if (tag_it != tags.end()) {
- build_tag_list_from_dense_nodes(builder, tag_it, tags.end());
+ osmium::builder::TagListBuilder tl_builder(m_buffer, &builder);
+ while (tag_it != tags.end() && *tag_it != 0) {
+ const auto& k = m_stringtable.at(*tag_it++);
+ if (tag_it == tags.end()) {
+ throw osmium::pbf_error("PBF format error"); // this is against the spec, keys/vals must come in pairs
+ }
+ const auto& v = m_stringtable.at(*tag_it++);
+ tl_builder.add_tag(k.first, k.second, v.first, v.second);
+ }
+
+ if (tag_it != tags.end()) {
+ ++tag_it;
+ }
}
+
+ m_buffer.commit();
}
}
public:
- PBFPrimitiveBlockDecoder(const data_view& data, osmium::osm_entity_bits::type read_types, osmium::io::read_meta read_metadata) :
+ PBFPrimitiveBlockDecoder(const data_view& data, osmium::osm_entity_bits::type read_types) :
m_data(data),
- m_read_types(read_types),
- m_read_metadata(read_metadata) {
+ m_read_types(read_types) {
}
PBFPrimitiveBlockDecoder(const PBFPrimitiveBlockDecoder&) = delete;
@@ -869,14 +789,12 @@ namespace osmium {
std::shared_ptr<std::string> m_input_buffer;
osmium::osm_entity_bits::type m_read_types;
- osmium::io::read_meta m_read_metadata;
public:
- PBFDataBlobDecoder(std::string&& input_buffer, osmium::osm_entity_bits::type read_types, osmium::io::read_meta read_metadata) :
+ PBFDataBlobDecoder(std::string&& input_buffer, osmium::osm_entity_bits::type read_types) :
m_input_buffer(std::make_shared<std::string>(std::move(input_buffer))),
- m_read_types(read_types),
- m_read_metadata(read_metadata) {
+ m_read_types(read_types) {
}
PBFDataBlobDecoder(const PBFDataBlobDecoder&) = default;
@@ -889,7 +807,7 @@ namespace osmium {
osmium::memory::Buffer operator()() {
std::string output;
- PBFPrimitiveBlockDecoder decoder(decode_blob(*m_input_buffer, output), m_read_types, m_read_metadata);
+ PBFPrimitiveBlockDecoder decoder(decode_blob(*m_input_buffer, output), m_read_types);
return decoder();
}
diff --git a/include/osmium/io/detail/pbf_input_format.hpp b/include/osmium/io/detail/pbf_input_format.hpp
index 31e778a..1253447 100644
--- a/include/osmium/io/detail/pbf_input_format.hpp
+++ b/include/osmium/io/detail/pbf_input_format.hpp
@@ -180,7 +180,7 @@ namespace osmium {
while (const auto size = check_type_and_get_blob_size("OSMData")) {
std::string input_buffer = read_from_input_queue_with_check(size);
- PBFDataBlobDecoder data_blob_parser{std::move(input_buffer), read_types(), read_metadata()};
+ PBFDataBlobDecoder data_blob_parser{ std::move(input_buffer), read_types() };
if (osmium::config::use_pool_threads_for_pbf_parsing()) {
send_to_output_queue(osmium::thread::Pool::instance().submit(std::move(data_blob_parser)));
@@ -195,8 +195,8 @@ namespace osmium {
PBFParser(future_string_queue_type& input_queue,
future_buffer_queue_type& output_queue,
std::promise<osmium::io::Header>& header_promise,
- osmium::io::detail::reader_options options) :
- Parser(input_queue, output_queue, header_promise, options),
+ osmium::osm_entity_bits::type read_types) :
+ Parser(input_queue, output_queue, header_promise, read_types),
m_input_buffer() {
}
@@ -221,8 +221,8 @@ namespace osmium {
[](future_string_queue_type& input_queue,
future_buffer_queue_type& output_queue,
std::promise<osmium::io::Header>& header_promise,
- osmium::io::detail::reader_options options) {
- return std::unique_ptr<Parser>(new PBFParser(input_queue, output_queue, header_promise, options));
+ osmium::osm_entity_bits::type read_which_entities) {
+ return std::unique_ptr<Parser>(new PBFParser(input_queue, output_queue, header_promise, read_which_entities));
});
// dummy function to silence the unused variable warning from above
diff --git a/include/osmium/io/detail/queue_util.hpp b/include/osmium/io/detail/queue_util.hpp
index 021ea7d..bc47020 100644
--- a/include/osmium/io/detail/queue_util.hpp
+++ b/include/osmium/io/detail/queue_util.hpp
@@ -33,10 +33,10 @@ DEALINGS IN THE SOFTWARE.
*/
+#include <algorithm>
#include <exception>
#include <future>
#include <string>
-#include <utility>
#include <osmium/memory/buffer.hpp>
#include <osmium/thread/queue.hpp>
@@ -63,6 +63,13 @@ namespace osmium {
* This type of queue contains OSM file data in the form it is
* stored on disk, ie encoded as XML, PBF, etc.
* The "end of file" is marked by an empty string.
+ */
+ using string_queue_type = osmium::thread::Queue<std::string>;
+
+ /**
+ * This type of queue contains OSM file data in the form it is
+ * stored on disk, ie encoded as XML, PBF, etc.
+ * The "end of file" is marked by an empty string.
* The strings are wrapped in a std::future so that they can also
* transport exceptions. The future also helps with keeping the
* data in order.
@@ -88,11 +95,11 @@ namespace osmium {
add_to_queue<T>(queue, T{});
}
- inline bool at_end_of_data(const std::string& data) noexcept {
+ inline bool at_end_of_data(const std::string& data) {
return data.empty();
}
- inline bool at_end_of_data(osmium::memory::Buffer& buffer) noexcept {
+ inline bool at_end_of_data(osmium::memory::Buffer& buffer) {
return !buffer;
}
diff --git a/include/osmium/io/detail/xml_input_format.hpp b/include/osmium/io/detail/xml_input_format.hpp
index 242ef9b..d8c57d8 100644
--- a/include/osmium/io/detail/xml_input_format.hpp
+++ b/include/osmium/io/detail/xml_input_format.hpp
@@ -80,8 +80,8 @@ namespace osmium {
XML_Error error_code;
std::string error_string;
- explicit xml_error(const XML_Parser& parser) :
- io_error(std::string{"XML parsing error at line "}
+ explicit xml_error(XML_Parser parser) :
+ io_error(std::string("XML parsing error at line ")
+ std::to_string(XML_GetCurrentLineNumber(parser))
+ ", column "
+ std::to_string(XML_GetCurrentColumnNumber(parser))
@@ -117,7 +117,7 @@ namespace osmium {
}
explicit format_version_error(const char* v) :
- io_error(std::string{"Can not read file with version "} + v),
+ io_error(std::string("Can not read file with version ") + v),
version(v) {
}
@@ -201,7 +201,7 @@ namespace osmium {
static void entity_declaration_handler(void*,
const XML_Char*, int, const XML_Char*, int, const XML_Char*,
const XML_Char*, const XML_Char*, const XML_Char*) {
- throw osmium::xml_error{"XML entities are not supported"};
+ throw osmium::xml_error("XML entities are not supported");
}
public:
@@ -209,7 +209,7 @@ namespace osmium {
explicit ExpatXMLParser(T* callback_object) :
m_parser(XML_ParserCreate(nullptr)) {
if (!m_parser) {
- throw osmium::io_error{"Internal error: Can not create parser"};
+ throw osmium::io_error("Internal error: Can not create parser");
}
XML_SetUserData(m_parser, callback_object);
XML_SetElementHandler(m_parser, start_element_wrapper, end_element_wrapper);
@@ -229,7 +229,7 @@ namespace osmium {
void operator()(const std::string& data, bool last) {
if (XML_Parse(m_parser, data.data(), static_cast_with_assert<int>(data.size()), last) == XML_STATUS_ERROR) {
- throw osmium::xml_error{m_parser};
+ throw osmium::xml_error(m_parser);
}
}
@@ -271,32 +271,37 @@ namespace osmium {
return user;
}
- void init_changeset(osmium::builder::ChangesetBuilder& builder, const XML_Char** attrs) {
- osmium::Box box;
+ void init_changeset(osmium::builder::ChangesetBuilder* builder, const XML_Char** attrs) {
+ const char* user = "";
+ osmium::Changeset& new_changeset = builder->object();
- check_attributes(attrs, [&builder, &box](const XML_Char* name, const XML_Char* value) {
+ osmium::Location min;
+ osmium::Location max;
+ check_attributes(attrs, [&min, &max, &user, &new_changeset](const XML_Char* name, const XML_Char* value) {
if (!std::strcmp(name, "min_lon")) {
- box.bottom_left().set_lon(value);
+ min.set_lon(value);
} else if (!std::strcmp(name, "min_lat")) {
- box.bottom_left().set_lat(value);
+ min.set_lat(value);
} else if (!std::strcmp(name, "max_lon")) {
- box.top_right().set_lon(value);
+ max.set_lon(value);
} else if (!std::strcmp(name, "max_lat")) {
- box.top_right().set_lat(value);
+ max.set_lat(value);
} else if (!std::strcmp(name, "user")) {
- builder.set_user(value);
+ user = value;
} else {
- builder.set_attribute(name, value);
+ new_changeset.set_attribute(name, value);
}
});
- builder.set_bounds(box);
+ new_changeset.bounds().extend(min);
+ new_changeset.bounds().extend(max);
+
+ builder->add_user(user);
}
- void get_tag(osmium::builder::Builder& builder, const XML_Char** attrs) {
+ void get_tag(osmium::builder::Builder* builder, const XML_Char** attrs) {
const char* k = "";
const char* v = "";
-
check_attributes(attrs, [&k, &v](const XML_Char* name, const XML_Char* value) {
if (name[0] == 'k' && name[1] == 0) {
k = value;
@@ -304,9 +309,8 @@ namespace osmium {
v = value;
}
});
-
if (!m_tl_builder) {
- m_tl_builder.reset(new osmium::builder::TagListBuilder{builder});
+ m_tl_builder = std::unique_ptr<osmium::builder::TagListBuilder>(new osmium::builder::TagListBuilder(m_buffer, builder));
}
m_tl_builder->add_tag(k, v);
}
@@ -326,17 +330,17 @@ namespace osmium {
if (!std::strcmp(name, "version")) {
m_header.set("version", value);
if (std::strcmp(value, "0.6")) {
- throw osmium::format_version_error{value};
+ throw osmium::format_version_error(value);
}
} else if (!std::strcmp(name, "generator")) {
m_header.set("generator", value);
}
});
if (m_header.get("version") == "") {
- throw osmium::format_version_error{};
+ throw osmium::format_version_error();
}
} else {
- throw osmium::xml_error{std::string{"Unknown top-level element: "} + element};
+ throw osmium::xml_error(std::string("Unknown top-level element: ") + element);
}
m_context = context::top;
break;
@@ -345,8 +349,8 @@ namespace osmium {
if (!std::strcmp(element, "node")) {
mark_header_as_done();
if (read_types() & osmium::osm_entity_bits::node) {
- m_node_builder.reset(new osmium::builder::NodeBuilder{m_buffer});
- m_node_builder->set_user(init_object(m_node_builder->object(), attrs));
+ m_node_builder = std::unique_ptr<osmium::builder::NodeBuilder>(new osmium::builder::NodeBuilder(m_buffer));
+ m_node_builder->add_user(init_object(m_node_builder->object(), attrs));
m_context = context::node;
} else {
m_context = context::ignored_node;
@@ -354,8 +358,8 @@ namespace osmium {
} else if (!std::strcmp(element, "way")) {
mark_header_as_done();
if (read_types() & osmium::osm_entity_bits::way) {
- m_way_builder.reset(new osmium::builder::WayBuilder{m_buffer});
- m_way_builder->set_user(init_object(m_way_builder->object(), attrs));
+ m_way_builder = std::unique_ptr<osmium::builder::WayBuilder>(new osmium::builder::WayBuilder(m_buffer));
+ m_way_builder->add_user(init_object(m_way_builder->object(), attrs));
m_context = context::way;
} else {
m_context = context::ignored_way;
@@ -363,8 +367,8 @@ namespace osmium {
} else if (!std::strcmp(element, "relation")) {
mark_header_as_done();
if (read_types() & osmium::osm_entity_bits::relation) {
- m_relation_builder.reset(new osmium::builder::RelationBuilder{m_buffer});
- m_relation_builder->set_user(init_object(m_relation_builder->object(), attrs));
+ m_relation_builder = std::unique_ptr<osmium::builder::RelationBuilder>(new osmium::builder::RelationBuilder(m_buffer));
+ m_relation_builder->add_user(init_object(m_relation_builder->object(), attrs));
m_context = context::relation;
} else {
m_context = context::ignored_relation;
@@ -372,8 +376,8 @@ namespace osmium {
} else if (!std::strcmp(element, "changeset")) {
mark_header_as_done();
if (read_types() & osmium::osm_entity_bits::changeset) {
- m_changeset_builder.reset(new osmium::builder::ChangesetBuilder{m_buffer});
- init_changeset(*m_changeset_builder, attrs);
+ m_changeset_builder = std::unique_ptr<osmium::builder::ChangesetBuilder>(new osmium::builder::ChangesetBuilder(m_buffer));
+ init_changeset(m_changeset_builder.get(), attrs);
m_context = context::changeset;
} else {
m_context = context::ignored_changeset;
@@ -403,7 +407,7 @@ namespace osmium {
m_last_context = context::node;
m_context = context::in_object;
if (!std::strcmp(element, "tag")) {
- get_tag(*m_node_builder, attrs);
+ get_tag(m_node_builder.get(), attrs);
}
break;
case context::way:
@@ -413,7 +417,7 @@ namespace osmium {
m_tl_builder.reset();
if (!m_wnl_builder) {
- m_wnl_builder.reset(new osmium::builder::WayNodeListBuilder{*m_way_builder});
+ m_wnl_builder = std::unique_ptr<osmium::builder::WayNodeListBuilder>(new osmium::builder::WayNodeListBuilder(m_buffer, m_way_builder.get()));
}
NodeRef nr;
@@ -429,7 +433,7 @@ namespace osmium {
m_wnl_builder->add_node_ref(nr);
} else if (!std::strcmp(element, "tag")) {
m_wnl_builder.reset();
- get_tag(*m_way_builder, attrs);
+ get_tag(m_way_builder.get(), attrs);
}
break;
case context::relation:
@@ -439,7 +443,7 @@ namespace osmium {
m_tl_builder.reset();
if (!m_rml_builder) {
- m_rml_builder.reset(new osmium::builder::RelationMemberListBuilder{*m_relation_builder});
+ m_rml_builder = std::unique_ptr<osmium::builder::RelationMemberListBuilder>(new osmium::builder::RelationMemberListBuilder(m_buffer, m_relation_builder.get()));
}
item_type type = item_type::undefined;
@@ -455,15 +459,15 @@ namespace osmium {
}
});
if (type != item_type::node && type != item_type::way && type != item_type::relation) {
- throw osmium::xml_error{"Unknown type on relation member"};
+ throw osmium::xml_error("Unknown type on relation member");
}
if (ref == 0) {
- throw osmium::xml_error{"Missing ref on relation member"};
+ throw osmium::xml_error("Missing ref on relation member");
}
m_rml_builder->add_member(type, ref, role);
} else if (!std::strcmp(element, "tag")) {
m_rml_builder.reset();
- get_tag(*m_relation_builder, attrs);
+ get_tag(m_relation_builder.get(), attrs);
}
break;
case context::changeset:
@@ -472,12 +476,12 @@ namespace osmium {
m_context = context::discussion;
m_tl_builder.reset();
if (!m_changeset_discussion_builder) {
- m_changeset_discussion_builder.reset(new osmium::builder::ChangesetDiscussionBuilder{*m_changeset_builder});
+ m_changeset_discussion_builder = std::unique_ptr<osmium::builder::ChangesetDiscussionBuilder>(new osmium::builder::ChangesetDiscussionBuilder(m_buffer, m_changeset_builder.get()));
}
} else if (!std::strcmp(element, "tag")) {
m_context = context::in_object;
m_changeset_discussion_builder.reset();
- get_tag(*m_changeset_builder, attrs);
+ get_tag(m_changeset_builder.get(), attrs);
}
break;
case context::discussion:
@@ -628,8 +632,8 @@ namespace osmium {
XMLParser(future_string_queue_type& input_queue,
future_buffer_queue_type& output_queue,
std::promise<osmium::io::Header>& header_promise,
- osmium::io::detail::reader_options options) :
- Parser(input_queue, output_queue, header_promise, options),
+ osmium::osm_entity_bits::type read_types) :
+ Parser(input_queue, output_queue, header_promise, read_types),
m_context(context::root),
m_last_context(context::root),
m_in_delete_section(false),
@@ -653,7 +657,7 @@ namespace osmium {
ExpatXMLParser<XMLParser> parser(this);
while (!input_done()) {
- const std::string data{get_input()};
+ std::string data = get_input();
parser(data, input_done());
if (read_types() == osmium::osm_entity_bits::nothing && header_is_done()) {
break;
@@ -676,8 +680,8 @@ namespace osmium {
[](future_string_queue_type& input_queue,
future_buffer_queue_type& output_queue,
std::promise<osmium::io::Header>& header_promise,
- osmium::io::detail::reader_options options) {
- return std::unique_ptr<Parser>(new XMLParser{input_queue, output_queue, header_promise, options});
+ osmium::osm_entity_bits::type read_which_entities) {
+ return std::unique_ptr<Parser>(new XMLParser(input_queue, output_queue, header_promise, read_which_entities));
});
// dummy function to silence the unused variable warning from above
diff --git a/include/osmium/io/file_format.hpp b/include/osmium/io/file_format.hpp
index 72b4abc..c447cb4 100644
--- a/include/osmium/io/file_format.hpp
+++ b/include/osmium/io/file_format.hpp
@@ -49,11 +49,6 @@ namespace osmium {
debug = 6
};
- enum class read_meta {
- no = 0,
- yes = 1
- };
-
// avoid g++ false positive
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wreturn-type"
diff --git a/include/osmium/io/header.hpp b/include/osmium/io/header.hpp
index abd85f8..55ff5c6 100644
--- a/include/osmium/io/header.hpp
+++ b/include/osmium/io/header.hpp
@@ -44,37 +44,17 @@ namespace osmium {
namespace io {
/**
- * Meta information from the header of an OSM file.
- *
- * The header can contain any number of bounding boxes, although
- * usually there is only a single one (or none). PBF files only
- * allow a single bounding box, but XML files can have multiple ones,
- * although it is unusual and the semantics are unclear, so it is
- * discouraged to create files with multiple bounding boxes.
- *
- * The header contains a flag telling you whether this file can
- * contain multiple versions of the same object. This is true for
- * history files and for change files, but not for normal OSM data
- * files. Not all OSM file formats can distinguish between those
- * cases, so the flag might be wrong.
- *
- * In addition the header can contain any number of key-value pairs
- * with additional information. Most often this is used to set the
- * "generator", the program that generated the file. Depending on
- * the file format some of these key-value pairs are handled
- * specially. The the Options parent class for details on how to
- * set and get those key-value pairs.
- */
+ * Meta information from the header of an OSM file.
+ */
class Header : public osmium::util::Options {
/// Bounding boxes
std::vector<osmium::Box> m_boxes;
/**
- * Are there possibly multiple versions of the same object in
- * this stream of objects? This should be true for history files
- * and for change files, but not for normal OSM data files.
- */
+ * Are there possibly multiple versions of the same object in this stream of objects?
+ * This is true for history files and for change files, but not for normal OSM files.
+ */
bool m_has_multiple_object_versions = false;
public:
@@ -85,76 +65,49 @@ namespace osmium {
Options(values) {
}
- /**
- * Get the bounding boxes defined in the header.
- */
+ Header(const Header&) = default;
+ Header& operator=(const Header&) = default;
+
+ Header(Header&&) = default;
+ Header& operator=(Header&&) = default;
+
+ ~Header() = default;
+
std::vector<osmium::Box>& boxes() noexcept {
return m_boxes;
}
- /**
- * Get the bounding boxes defined in the header.
- */
const std::vector<osmium::Box>& boxes() const noexcept {
return m_boxes;
}
- /**
- * Set all the bounding boxes in the header.
- */
Header& boxes(const std::vector<osmium::Box>& boxes) noexcept {
m_boxes = boxes;
return *this;
}
- /**
- * Get the first (or only if there is only one) bounding box.
- *
- * Returns an empty, invalid box if there is none.
- */
osmium::Box box() const {
- return m_boxes.empty() ? osmium::Box{} : m_boxes.front();
+ return m_boxes.empty() ? osmium::Box() : m_boxes.front();
}
- /**
- * Join up all the bounding boxes in the header into one and return
- * it. This method is what you probably want to use unless you want
- * to handle the possibly multiple bounding boxes yourself.
- *
- * Returns an empty, invalid box if there is none.
- */
osmium::Box joined_boxes() const {
osmium::Box box;
for (const auto& b : m_boxes) {
- box.extend(b);
+ box.extend(b.bottom_left());
+ box.extend(b.top_right());
}
return box;
}
- /**
- * Add the given bounding box to the list of bounding boxes in the
- * header.
- *
- * @returns The header itself to allow chaining.
- */
Header& add_box(const osmium::Box& box) {
m_boxes.push_back(box);
return *this;
}
- /**
- * Can this file contain multiple versions of the same object?
- */
bool has_multiple_object_versions() const noexcept {
return m_has_multiple_object_versions;
}
- /**
- * Set the flag that tells us whether this file can contain
- * multiple versions of the same object?
- *
- * @returns The header itself to allow chaining.
- */
Header& set_has_multiple_object_versions(bool value) noexcept {
m_has_multiple_object_versions = value;
return *this;
diff --git a/include/osmium/io/reader.hpp b/include/osmium/io/reader.hpp
index 89c8564..12f97b8 100644
--- a/include/osmium/io/reader.hpp
+++ b/include/osmium/io/reader.hpp
@@ -91,6 +91,7 @@ namespace osmium {
class Reader {
osmium::io::File m_file;
+ osmium::osm_entity_bits::type m_read_which_entities;
enum class status {
okay = 0, // normal reading
@@ -117,25 +118,15 @@ namespace osmium {
size_t m_file_size;
- osmium::io::detail::reader_options m_options;
-
- void set_option(osmium::osm_entity_bits::type value) noexcept {
- m_options.read_which_entities = value;
- }
-
- void set_option(osmium::io::read_meta value) noexcept {
- m_options.read_metadata = value;
- }
-
// This function will run in a separate thread.
static void parser_thread(const osmium::io::File& file,
detail::future_string_queue_type& input_queue,
detail::future_buffer_queue_type& osmdata_queue,
std::promise<osmium::io::Header>&& header_promise,
- osmium::io::detail::reader_options options) {
+ osmium::osm_entity_bits::type read_which_entities) {
std::promise<osmium::io::Header> promise = std::move(header_promise);
const auto creator = detail::ParserFactory::instance().get_creator_function(file);
- const auto parser = creator(input_queue, osmdata_queue, promise, options);
+ const auto parser = creator(input_queue, osmdata_queue, promise, read_which_entities);
parser->parse();
}
@@ -214,28 +205,15 @@ namespace osmium {
/**
* Create new Reader object.
*
- * @param file The file (contains name and format info) to open.
- * @param args All further arguments are optional and can appear
- * in any order:
- *
- * * osmium::osm_entities::bits: Which OSM entities (nodes, ways,
- * relations, and/or changesets) should be read from the
- * input file. It can speed the read up significantly if
- * objects that are not needed anyway are not parsed.
- *
- * * osmium::io::read_meta: Read meta data or not. The default is
- * osmium::io::read_meta::yes which means that meta data
- * is read normally. If you set this to
- * osmium::io::read_meta::no, meta data (like version, uid,
- * etc.) is not read possibly speeding up the read. Not all
- * file formats use this setting.
- *
- * @throws osmium::io_error If there was an error.
- * @throws std::system_error If the file could not be opened.
+ * @param file The file we want to open.
+ * @param read_which_entities Which OSM entities (nodes, ways, relations, and/or changesets)
+ * should be read from the input file. It can speed the read up
+ * significantly if objects that are not needed anyway are not
+ * parsed.
*/
- template <typename... TArgs>
- explicit Reader(const osmium::io::File& file, TArgs&&... args) :
+ explicit Reader(const osmium::io::File& file, osmium::osm_entity_bits::type read_which_entities = osmium::osm_entity_bits::all) :
m_file(file.check()),
+ m_read_which_entities(read_which_entities),
m_status(status::okay),
m_childpid(0),
m_input_queue(detail::get_input_queue_size(), "raw_input"),
@@ -249,24 +227,17 @@ namespace osmium {
m_header(),
m_thread(),
m_file_size(m_decompressor->file_size()) {
-
- (void)std::initializer_list<int>{
- (set_option(args), 0)...
- };
-
std::promise<osmium::io::Header> header_promise;
m_header_future = header_promise.get_future();
- m_thread = osmium::thread::thread_handler{parser_thread, std::ref(m_file), std::ref(m_input_queue), std::ref(m_osmdata_queue), std::move(header_promise), m_options};
+ m_thread = osmium::thread::thread_handler{parser_thread, std::ref(m_file), std::ref(m_input_queue), std::ref(m_osmdata_queue), std::move(header_promise), read_which_entities};
}
- template <typename... TArgs>
- explicit Reader(const std::string& filename, TArgs&&... args) :
- Reader(osmium::io::File(filename), std::forward<TArgs>(args)...) {
+ explicit Reader(const std::string& filename, osmium::osm_entity_bits::type read_types = osmium::osm_entity_bits::all) :
+ Reader(osmium::io::File(filename), read_types) {
}
- template <typename... TArgs>
- explicit Reader(const char* filename, TArgs&&... args) :
- Reader(osmium::io::File(filename), std::forward<TArgs>(args)...) {
+ explicit Reader(const char* filename, osmium::osm_entity_bits::type read_types = osmium::osm_entity_bits::all) :
+ Reader(osmium::io::File(filename), read_types) {
}
Reader(const Reader&) = delete;
@@ -333,7 +304,7 @@ namespace osmium {
try {
if (m_header_future.valid()) {
m_header = m_header_future.get();
- if (m_options.read_which_entities == osmium::osm_entity_bits::nothing) {
+ if (m_read_which_entities == osmium::osm_entity_bits::nothing) {
m_status = status::eof;
}
}
@@ -359,7 +330,7 @@ namespace osmium {
osmium::memory::Buffer buffer;
if (m_status != status::okay ||
- m_options.read_which_entities == osmium::osm_entity_bits::nothing) {
+ m_read_which_entities == osmium::osm_entity_bits::nothing) {
throw io_error("Can not read from reader when in status 'closed', 'eof', or 'error'");
}
diff --git a/include/osmium/memory/buffer.hpp b/include/osmium/memory/buffer.hpp
index bcf0bd0..8c246db 100644
--- a/include/osmium/memory/buffer.hpp
+++ b/include/osmium/memory/buffer.hpp
@@ -113,9 +113,6 @@ namespace osmium {
size_t m_capacity;
size_t m_written;
size_t m_committed;
-#ifndef NDEBUG
- uint8_t m_builder_count{0};
-#endif
auto_grow m_auto_grow {auto_grow::no};
std::function<void(Buffer&)> m_full;
@@ -219,28 +216,13 @@ namespace osmium {
~Buffer() = default;
-#ifndef NDEBUG
- void increment_builder_count() noexcept {
- ++m_builder_count;
- }
-
- void decrement_builder_count() noexcept {
- assert(m_builder_count > 0);
- --m_builder_count;
- }
-
- uint8_t builder_count() const noexcept {
- return m_builder_count;
- }
-#endif
-
/**
* Return a pointer to data inside the buffer.
*
* @pre The buffer must be valid.
*/
unsigned char* data() const noexcept {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return m_data;
}
@@ -276,7 +258,7 @@ namespace osmium {
* @pre The buffer must be valid.
*/
bool is_aligned() const noexcept {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return (m_written % align_bytes == 0) && (m_committed % align_bytes == 0);
}
@@ -301,7 +283,7 @@ namespace osmium {
* than the difference between committed() and capacity().
*/
OSMIUM_DEPRECATED void set_full_callback(std::function<void(Buffer&)> full) {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
m_full = full;
}
@@ -310,6 +292,7 @@ namespace osmium {
* This works only with internally memory-managed buffers.
* If the given size is not larger than the current capacity,
* nothing is done.
+ * Already written but not committed data is discarded.
*
* @pre The buffer must be valid.
*
@@ -322,7 +305,7 @@ namespace osmium {
* @throws std::bad_alloc if there isn't enough memory available.
*/
void grow(size_t size) {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
if (!m_memory) {
throw std::logic_error("Can't grow Buffer if it doesn't use internal memory management.");
}
@@ -342,18 +325,15 @@ namespace osmium {
/**
* Mark currently written bytes in the buffer as committed.
*
- * @pre The buffer must be valid.
- * @pre The buffer must be aligned properly (as indicated
+ * @pre The buffer must be valid and aligned properly (as indicated
* by is_aligned().
- * @pre No builder can be open on this buffer.
*
* @returns Number of committed bytes before this commit. Can be
* used as an offset into the buffer to get to the
* object being committed by this call.
*/
size_t commit() {
- assert(m_data && "This must be a valid buffer");
- assert(m_builder_count == 0 && "Make sure there are no Builder objects still in scope");
+ assert(m_data);
assert(is_aligned());
const size_t offset = m_committed;
@@ -365,11 +345,9 @@ namespace osmium {
* Roll back changes in buffer to last committed state.
*
* @pre The buffer must be valid.
- * @pre No builder can be open on this buffer.
*/
void rollback() {
- assert(m_data && "This must be a valid buffer");
- assert(m_builder_count == 0 && "Make sure there are no Builder objects still in scope");
+ assert(m_data);
m_written = m_committed;
}
@@ -378,12 +356,9 @@ namespace osmium {
*
* No-op on an invalid buffer.
*
- * @pre No builder can be open on this buffer.
- *
* @returns Number of bytes in the buffer before it was cleared.
*/
size_t clear() {
- assert(m_builder_count == 0 && "Make sure there are no Builder objects still in scope");
const size_t committed = m_committed;
m_written = 0;
m_committed = 0;
@@ -402,7 +377,7 @@ namespace osmium {
*/
template <typename T>
T& get(const size_t offset) const {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return *reinterpret_cast<T*>(&m_data[offset]);
}
@@ -440,7 +415,7 @@ namespace osmium {
* no callback defined and the buffer isn't auto-growing.
*/
unsigned char* reserve_space(const size_t size) {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
// try to flush the buffer empty first.
if (m_written + size > m_capacity && m_full) {
m_full(*this);
@@ -480,7 +455,7 @@ namespace osmium {
*/
template <typename T>
T& add_item(const T& item) {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
unsigned char* target = reserve_space(item.padded_size());
std::copy_n(reinterpret_cast<const unsigned char*>(&item), item.padded_size(), target);
return *reinterpret_cast<T*>(target);
@@ -490,7 +465,6 @@ namespace osmium {
* Add committed contents of the given buffer to this buffer.
*
* @pre The buffer must be valid.
- * @pre No builder can be open on this buffer.
*
* Note that you have to eventually call commit() to actually
* commit this data.
@@ -498,9 +472,7 @@ namespace osmium {
* @param buffer The source of the copy. Must be valid.
*/
void add_buffer(const Buffer& buffer) {
- assert(m_data && "This must be a valid buffer");
- assert(buffer && "Buffer parameter must be a valid buffer");
- assert(m_builder_count == 0 && "Make sure there are no Builder objects still in scope");
+ assert(m_data && buffer);
unsigned char* target = reserve_space(buffer.committed());
std::copy_n(buffer.data(), buffer.committed(), target);
}
@@ -510,13 +482,11 @@ namespace osmium {
* you can use std::back_inserter.
*
* @pre The buffer must be valid.
- * @pre No builder can be open on this buffer.
*
* @param item The item to be added.
*/
void push_back(const osmium::memory::Item& item) {
- assert(m_data && "This must be a valid buffer");
- assert(m_builder_count == 0 && "Make sure there are no Builder objects still in scope");
+ assert(m_data);
add_item(item);
commit();
}
@@ -567,7 +537,7 @@ namespace osmium {
*/
template <typename T>
t_iterator<T> begin() {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return t_iterator<T>(m_data, m_data + m_committed);
}
@@ -580,7 +550,7 @@ namespace osmium {
* @returns Iterator to first OSMEntity in the buffer.
*/
iterator begin() {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return iterator(m_data, m_data + m_committed);
}
@@ -595,7 +565,7 @@ namespace osmium {
*/
template <typename T>
t_iterator<T> get_iterator(size_t offset) {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return t_iterator<T>(m_data + offset, m_data + m_committed);
}
@@ -609,7 +579,7 @@ namespace osmium {
* buffer.
*/
iterator get_iterator(size_t offset) {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return iterator(m_data + offset, m_data + m_committed);
}
@@ -623,7 +593,7 @@ namespace osmium {
*/
template <typename T>
t_iterator<T> end() {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return t_iterator<T>(m_data + m_committed, m_data + m_committed);
}
@@ -636,40 +606,40 @@ namespace osmium {
* @returns End iterator.
*/
iterator end() {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return iterator(m_data + m_committed, m_data + m_committed);
}
template <typename T>
t_const_iterator<T> cbegin() const {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return t_const_iterator<T>(m_data, m_data + m_committed);
}
const_iterator cbegin() const {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return const_iterator(m_data, m_data + m_committed);
}
template <typename T>
t_const_iterator<T> get_iterator(size_t offset) const {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return t_const_iterator<T>(m_data + offset, m_data + m_committed);
}
const_iterator get_iterator(size_t offset) const {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return const_iterator(m_data + offset, m_data + m_committed);
}
template <typename T>
t_const_iterator<T> cend() const {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return t_const_iterator<T>(m_data + m_committed, m_data + m_committed);
}
const_iterator cend() const {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
return const_iterator(m_data + m_committed, m_data + m_committed);
}
@@ -728,7 +698,7 @@ namespace osmium {
*/
template <typename TCallbackClass>
void purge_removed(TCallbackClass* callback) {
- assert(m_data && "This must be a valid buffer");
+ assert(m_data);
if (begin() == end()) {
return;
}
diff --git a/include/osmium/memory/collection.hpp b/include/osmium/memory/collection.hpp
index fb413ff..2a2c040 100644
--- a/include/osmium/memory/collection.hpp
+++ b/include/osmium/memory/collection.hpp
@@ -46,9 +46,9 @@ namespace osmium {
template <typename TMember>
class CollectionIterator {
- // This data_type is either 'unsigned char*' or 'const unsigned
- // char*' depending on whether TMember is const. This allows this
- // class to be used as an iterator and as a const_iterator.
+ // This data_type is either 'unsigned char*' or 'const unsigned char*' depending
+ // on whether TMember is const. This allows this class to be used as an iterator and
+ // as a const_iterator.
using data_type = typename std::conditional<std::is_const<TMember>::value, const unsigned char*, unsigned char*>::type;
data_type m_data;
@@ -92,11 +92,11 @@ namespace osmium {
return m_data;
}
- TMember& operator*() const noexcept {
+ TMember& operator*() const {
return *reinterpret_cast<TMember*>(m_data);
}
- TMember* operator->() const noexcept {
+ TMember* operator->() const {
return reinterpret_cast<TMember*>(m_data);
}
@@ -118,12 +118,9 @@ namespace osmium {
public:
- using value_type = TMember;
- using reference = TMember&;
- using const_reference = const TMember&;
- using iterator = CollectionIterator<TMember>;
- using const_iterator = CollectionIterator<const TMember>;
- using size_type = size_t;
+ using iterator = CollectionIterator<TMember>;
+ using const_iterator = CollectionIterator<const TMember>;
+ using value_type = TMember;
static constexpr osmium::item_type itemtype = TCollectionItemType;
@@ -131,45 +128,31 @@ namespace osmium {
Item(sizeof(Collection<TMember, TCollectionItemType>), TCollectionItemType) {
}
- /**
- * Does this collection contain any items?
- *
- * Complexity: Constant.
- */
- bool empty() const noexcept {
+ bool empty() const {
return sizeof(Collection<TMember, TCollectionItemType>) == byte_size();
}
- /**
- * Returns the number of items in this collection.
- *
- * Complexity: Linear in the number of items.
- */
- size_type size() const noexcept {
- return static_cast<size_type>(std::distance(begin(), end()));
- }
-
- iterator begin() noexcept {
+ iterator begin() {
return iterator(data() + sizeof(Collection<TMember, TCollectionItemType>));
}
- iterator end() noexcept {
+ iterator end() {
return iterator(data() + byte_size());
}
- const_iterator cbegin() const noexcept {
+ const_iterator cbegin() const {
return const_iterator(data() + sizeof(Collection<TMember, TCollectionItemType>));
}
- const_iterator cend() const noexcept {
+ const_iterator cend() const {
return const_iterator(data() + byte_size());
}
- const_iterator begin() const noexcept {
+ const_iterator begin() const {
return cbegin();
}
- const_iterator end() const noexcept {
+ const_iterator end() const {
return cend();
}
diff --git a/include/osmium/memory/item.hpp b/include/osmium/memory/item.hpp
index b72ca4d..2df33c7 100644
--- a/include/osmium/memory/item.hpp
+++ b/include/osmium/memory/item.hpp
@@ -59,9 +59,9 @@ namespace osmium {
using item_size_type = uint32_t;
// align datastructures to this many bytes
- constexpr const item_size_type align_bytes = 8;
+ constexpr item_size_type align_bytes = 8;
- inline constexpr std::size_t padded_length(std::size_t length) noexcept {
+ inline std::size_t padded_length(std::size_t length) noexcept {
return (length + align_bytes - 1) & ~(align_bytes - 1);
}
diff --git a/include/osmium/osm/area.hpp b/include/osmium/osm/area.hpp
index d146e97..490fbe9 100644
--- a/include/osmium/osm/area.hpp
+++ b/include/osmium/osm/area.hpp
@@ -50,8 +50,7 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
namespace builder {
- template <typename TDerived, typename T>
- class OSMObjectBuilder;
+ template <class T> class ObjectBuilder;
} // namespace builder
/**
@@ -118,8 +117,7 @@ namespace osmium {
*/
class Area : public OSMObject {
- template <typename TDerived, typename T>
- friend class osmium::builder::OSMObjectBuilder;
+ friend class osmium::builder::ObjectBuilder<osmium::Area>;
Area() :
OSMObject(sizeof(Area), osmium::item_type::area) {
@@ -132,8 +130,6 @@ namespace osmium {
/**
* Was this area created from a way? (In contrast to areas
* created from a relation and their members.)
- *
- * Complexity: Constant.
*/
bool from_way() const noexcept {
return (positive_id() & 0x1) == 0;
@@ -141,8 +137,6 @@ namespace osmium {
/**
* Return the Id of the way or relation this area was created from.
- *
- * Complexity: Constant.
*/
osmium::object_id_type orig_id() const noexcept {
return osmium::area_id_to_object_id(id());
@@ -151,8 +145,6 @@ namespace osmium {
/**
* Count the number of outer and inner rings of this area.
*
- * Complexity: Linear in the number of rings.
- *
* @returns Pair (number outer rings, number inner rings)
*/
std::pair<size_t, size_t> num_rings() const {
diff --git a/include/osmium/osm/changeset.hpp b/include/osmium/osm/changeset.hpp
index 828a2c2..8a503ca 100644
--- a/include/osmium/osm/changeset.hpp
+++ b/include/osmium/osm/changeset.hpp
@@ -51,7 +51,7 @@ namespace osmium {
namespace builder {
class ChangesetDiscussionBuilder;
- class ChangesetBuilder;
+ template <typename T> class ObjectBuilder;
} // namespace builder
class Changeset;
@@ -129,12 +129,20 @@ namespace osmium {
class ChangesetDiscussion : public osmium::memory::Collection<ChangesetComment, osmium::item_type::changeset_discussion> {
+ friend class osmium::builder::ObjectBuilder<osmium::Changeset>;
+
public:
+ using size_type = size_t;
+
ChangesetDiscussion() :
osmium::memory::Collection<ChangesetComment, osmium::item_type::changeset_discussion>() {
}
+ size_type size() const noexcept {
+ return static_cast<size_type>(std::distance(begin(), end()));
+ }
+
}; // class ChangesetDiscussion
static_assert(sizeof(ChangesetDiscussion) % osmium::memory::align_bytes == 0, "Class osmium::ChangesetDiscussion has wrong size to be aligned properly!");
@@ -148,7 +156,7 @@ namespace osmium {
*/
class Changeset : public osmium::OSMEntity {
- friend class osmium::builder::ChangesetBuilder;
+ friend class osmium::builder::ObjectBuilder<osmium::Changeset>;
osmium::Box m_bounds;
osmium::Timestamp m_created_at;
@@ -165,14 +173,10 @@ namespace osmium {
OSMEntity(sizeof(Changeset), osmium::item_type::changeset) {
}
- void set_user_size(string_size_type size) noexcept {
+ void set_user_size(string_size_type size) {
m_user_size = size;
}
- string_size_type user_size() const noexcept {
- return m_user_size;
- }
-
unsigned char* subitems_position() {
return data() + osmium::memory::padded_length(sizeof(Changeset) + m_user_size);
}
diff --git a/include/osmium/osm/crc.hpp b/include/osmium/osm/crc.hpp
index bf057fd..2abeac4 100644
--- a/include/osmium/osm/crc.hpp
+++ b/include/osmium/osm/crc.hpp
@@ -100,15 +100,15 @@ namespace osmium {
return m_crc;
}
- void update_bool(const bool value) noexcept {
+ void update_bool(const bool value) {
m_crc.process_byte(value);
}
- void update_int8(const uint8_t value) noexcept {
+ void update_int8(const uint8_t value) {
m_crc.process_byte(value);
}
- void update_int16(const uint16_t value) noexcept {
+ void update_int16(const uint16_t value) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
m_crc.process_bytes(&value, sizeof(uint16_t));
#else
@@ -117,7 +117,7 @@ namespace osmium {
#endif
}
- void update_int32(const uint32_t value) noexcept {
+ void update_int32(const uint32_t value) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
m_crc.process_bytes(&value, sizeof(uint32_t));
#else
@@ -126,7 +126,7 @@ namespace osmium {
#endif
}
- void update_int64(const uint64_t value) noexcept {
+ void update_int64(const uint64_t value) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
m_crc.process_bytes(&value, sizeof(uint64_t));
#else
@@ -135,57 +135,57 @@ namespace osmium {
#endif
}
- void update_string(const char* str) noexcept {
+ void update_string(const char* str) {
while (*str) {
m_crc.process_byte(*str++);
}
}
- void update(const Timestamp& timestamp) noexcept {
+ void update(const Timestamp& timestamp) {
update_int32(uint32_t(timestamp));
}
- void update(const osmium::Location& location) noexcept {
+ void update(const osmium::Location& location) {
update_int32(location.x());
update_int32(location.y());
}
- void update(const osmium::Box& box) noexcept {
+ void update(const osmium::Box& box) {
update(box.bottom_left());
update(box.top_right());
}
- void update(const NodeRef& node_ref) noexcept {
+ void update(const NodeRef& node_ref) {
update_int64(node_ref.ref());
update(node_ref.location());
}
- void update(const NodeRefList& node_refs) noexcept {
+ void update(const NodeRefList& node_refs) {
for (const NodeRef& node_ref : node_refs) {
update(node_ref);
}
}
- void update(const TagList& tags) noexcept {
+ void update(const TagList& tags) {
for (const Tag& tag : tags) {
update_string(tag.key());
update_string(tag.value());
}
}
- void update(const osmium::RelationMember& member) noexcept {
+ void update(const osmium::RelationMember& member) {
update_int64(member.ref());
update_int16(uint16_t(member.type()));
update_string(member.role());
}
- void update(const osmium::RelationMemberList& members) noexcept {
+ void update(const osmium::RelationMemberList& members) {
for (const RelationMember& member : members) {
update(member);
}
}
- void update(const osmium::OSMObject& object) noexcept {
+ void update(const osmium::OSMObject& object) {
update_int64(object.id());
update_bool(object.visible());
update_int32(object.version());
@@ -195,22 +195,22 @@ namespace osmium {
update(object.tags());
}
- void update(const osmium::Node& node) noexcept {
+ void update(const osmium::Node& node) {
update(static_cast<const osmium::OSMObject&>(node));
update(node.location());
}
- void update(const osmium::Way& way) noexcept {
+ void update(const osmium::Way& way) {
update(static_cast<const osmium::OSMObject&>(way));
update(way.nodes());
}
- void update(const osmium::Relation& relation) noexcept {
+ void update(const osmium::Relation& relation) {
update(static_cast<const osmium::OSMObject&>(relation));
update(relation.members());
}
- void update(const osmium::Area& area) noexcept {
+ void update(const osmium::Area& area) {
update(static_cast<const osmium::OSMObject&>(area));
for (const auto& subitem : area) {
if (subitem.type() == osmium::item_type::outer_ring ||
@@ -220,7 +220,7 @@ namespace osmium {
}
}
- void update(const osmium::ChangesetDiscussion& discussion) noexcept {
+ void update(const osmium::ChangesetDiscussion& discussion) {
for (const auto& comment : discussion) {
update(comment.date());
update_int32(comment.uid());
@@ -229,7 +229,7 @@ namespace osmium {
}
}
- void update(const osmium::Changeset& changeset) noexcept {
+ void update(const osmium::Changeset& changeset) {
update_int64(changeset.id());
update(changeset.created_at());
update(changeset.closed_at());
diff --git a/include/osmium/osm/entity_bits.hpp b/include/osmium/osm/entity_bits.hpp
index 05afe3b..b8e9ddb 100644
--- a/include/osmium/osm/entity_bits.hpp
+++ b/include/osmium/osm/entity_bits.hpp
@@ -60,9 +60,7 @@ namespace osmium {
* assert(! (entities & osmium::osm_entity_bits::changeset));
* @endcode
*/
- enum type : unsigned char { // this should have been an enum class
- // but now we can't change it any more
- // without breaking lots of code
+ enum type : unsigned char {
nothing = 0x00,
node = 0x01,
@@ -77,21 +75,21 @@ namespace osmium {
}; // enum type
- inline constexpr type operator|(const type lhs, const type rhs) noexcept {
- return static_cast<type>(static_cast<int>(lhs) | static_cast<int>(rhs));
+ inline type operator|(const type lhs, const type rhs) noexcept {
+ return static_cast<type>(static_cast<int>(lhs) | static_cast<int> (rhs));
}
- inline constexpr type operator&(const type lhs, const type rhs) noexcept {
- return static_cast<type>(static_cast<int>(lhs) & static_cast<int>(rhs));
+ inline type& operator|=(type& lhs, const type rhs) noexcept {
+ lhs = lhs | rhs;
+ return lhs;
}
- inline constexpr type operator~(const type value) noexcept {
- return all & static_cast<type>(~static_cast<int>(value));
+ inline type operator&(const type lhs, const type rhs) noexcept {
+ return static_cast<type>(static_cast<int>(lhs) & static_cast<int> (rhs));
}
- inline type& operator|=(type& lhs, const type rhs) noexcept {
- lhs = lhs | rhs;
- return lhs;
+ inline type operator~(const type value) noexcept {
+ return static_cast<type>(~static_cast<int>(value));
}
inline type operator&=(type& lhs, const type rhs) noexcept {
@@ -106,7 +104,7 @@ namespace osmium {
* changeset.
*/
inline type from_item_type(osmium::item_type item_type) noexcept {
- const auto ut = static_cast<std::underlying_type<osmium::item_type>::type>(item_type);
+ auto ut = static_cast<std::underlying_type<osmium::item_type>::type>(item_type);
assert(ut <= 0x05);
if (ut == 0) {
return nothing;
diff --git a/include/osmium/osm/location.hpp b/include/osmium/osm/location.hpp
index d208717..c5da620 100644
--- a/include/osmium/osm/location.hpp
+++ b/include/osmium/osm/location.hpp
@@ -86,31 +86,23 @@ namespace osmium {
++str;
}
- if (*str != '.') {
- // there has to be at least one digit
- if (*str >= '0' && *str <= '9') {
- result = *str - '0';
- ++str;
- } else {
- goto error;
- }
+ // there has to be at least one digit
+ if (*str >= '0' && *str <= '9') {
+ result = *str - '0';
+ ++str;
+ } else {
+ goto error;
+ }
- // optional additional digits before decimal point
- while (*str >= '0' && *str <= '9' && max_digits > 0) {
- result = result * 10 + (*str - '0');
- ++str;
- --max_digits;
- }
+ // optional additional digits before decimal point
+ while (*str >= '0' && *str <= '9' && max_digits > 0) {
+ result = result * 10 + (*str - '0');
+ ++str;
+ --max_digits;
+ }
- if (max_digits == 0) {
- goto error;
- }
- } else {
- // need at least one digit after decimal dot if there was no
- // digit before decimal dot
- if (*(str + 1) < '0' || *(str + 1) > '9') {
- goto error;
- }
+ if (max_digits == 0) {
+ goto error;
}
// optional decimal point
@@ -171,20 +163,18 @@ namespace osmium {
}
if (scale < 0) {
- for (; scale < 0 && result > 0; ++scale) {
- result /= 10;
- }
+ result = 0;
} else {
for (; scale > 0; --scale) {
result *= 10;
}
- }
- result = (result + 5) / 10 * sign;
+ result = (result + 5) / 10 * sign;
- if (result > std::numeric_limits<int32_t>::max() ||
- result < std::numeric_limits<int32_t>::min()) {
- goto error;
+ if (result > std::numeric_limits<int32_t>::max() ||
+ result < std::numeric_limits<int32_t>::min()) {
+ goto error;
+ }
}
*data = str;
diff --git a/include/osmium/osm/node.hpp b/include/osmium/osm/node.hpp
index f3df5e9..677ffc7 100644
--- a/include/osmium/osm/node.hpp
+++ b/include/osmium/osm/node.hpp
@@ -41,14 +41,12 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
namespace builder {
- template <typename TDerived, typename T>
- class OSMObjectBuilder;
+ template <typename T> class ObjectBuilder;
} // namespace builder
class Node : public OSMObject {
- template <typename TDerived, typename T>
- friend class osmium::builder::OSMObjectBuilder;
+ friend class osmium::builder::ObjectBuilder<osmium::Node>;
osmium::Location m_location;
@@ -64,7 +62,7 @@ namespace osmium {
return m_location;
}
- Node& set_location(const osmium::Location& location) noexcept {
+ Node& set_location(const osmium::Location& location) {
m_location = location;
return *this;
}
diff --git a/include/osmium/osm/node_ref_list.hpp b/include/osmium/osm/node_ref_list.hpp
index f430b63..6cfdf22 100644
--- a/include/osmium/osm/node_ref_list.hpp
+++ b/include/osmium/osm/node_ref_list.hpp
@@ -52,23 +52,12 @@ namespace osmium {
public:
- using value_type = NodeRef;
- using reference = NodeRef&;
- using const_reference = const NodeRef&;
- using iterator = NodeRef*;
- using const_iterator = const NodeRef*;
- using const_reverse_iterator = std::reverse_iterator<const NodeRef*>;
- using difference_type = std::ptrdiff_t;
- using size_type = std::size_t;
-
explicit NodeRefList(osmium::item_type itemtype) noexcept :
osmium::memory::Item(sizeof(NodeRefList), itemtype) {
}
/**
* Checks whether the collection is empty.
- *
- * Complexity: Constant.
*/
bool empty() const noexcept {
return sizeof(NodeRefList) == byte_size();
@@ -76,10 +65,8 @@ namespace osmium {
/**
* Returns the number of NodeRefs in the collection.
- *
- * Complexity: Constant.
*/
- size_type size() const noexcept {
+ size_t size() const noexcept {
const auto size_node_refs = byte_size() - sizeof(NodeRefList);
assert(size_node_refs % sizeof(NodeRef) == 0);
return size_node_refs / sizeof(NodeRef);
@@ -88,13 +75,11 @@ namespace osmium {
/**
* Access specified element.
*
- * Complexity: Constant.
- *
* @pre @code n < size() @endcode
*
* @param n Get the n-th element of the collection.
*/
- const NodeRef& operator[](size_type n) const noexcept {
+ const NodeRef& operator[](size_t n) const noexcept {
assert(n < size());
const NodeRef* node_ref = &*(cbegin());
return node_ref[n];
@@ -103,8 +88,6 @@ namespace osmium {
/**
* Access the first element.
*
- * Complexity: Constant.
- *
* @pre @code !empty() @endcode
*/
const NodeRef& front() const noexcept {
@@ -115,8 +98,6 @@ namespace osmium {
/**
* Access the last element.
*
- * Complexity: Constant.
- *
* @pre @code !empty() @endcode
*/
const NodeRef& back() const noexcept {
@@ -128,8 +109,6 @@ namespace osmium {
* Checks whether the first and last node in the collection have the
* same ID. The locations are not checked.
*
- * Complexity: Constant.
- *
* @pre @code !empty() @endcode
*/
bool is_closed() const noexcept {
@@ -140,8 +119,6 @@ namespace osmium {
* Checks whether the first and last node in the collection have the
* same ID. The locations are not checked.
*
- * Complexity: Constant.
- *
* @pre @code !empty() @endcode
*/
bool ends_have_same_id() const noexcept {
@@ -152,8 +129,6 @@ namespace osmium {
* Checks whether the first and last node in the collection have the
* same location. The IDs are not checked.
*
- * Complexity: Constant.
- *
* @pre @code !empty() @endcode
* @pre @code front().location() && back().location() @endcode
*/
@@ -162,6 +137,10 @@ namespace osmium {
return front().location() == back().location();
}
+ using iterator = NodeRef*;
+ using const_iterator = const NodeRef*;
+ using const_reverse_iterator = std::reverse_iterator<const NodeRef*>;
+
/// Returns an iterator to the beginning.
iterator begin() noexcept {
return iterator(data() + sizeof(NodeRefList));
diff --git a/include/osmium/osm/object.hpp b/include/osmium/osm/object.hpp
index 01fe249..caa6fbc 100644
--- a/include/osmium/osm/object.hpp
+++ b/include/osmium/osm/object.hpp
@@ -52,19 +52,11 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
- namespace builder {
- template <typename TDerived, typename T>
- class OSMObjectBuilder;
- } // namespace builder
-
/**
* OSMObject (Node, Way, Relation, or Area).
*/
class OSMObject : public osmium::OSMEntity {
- template <typename TDerived, typename T>
- friend class osmium::builder::OSMObjectBuilder;
-
object_id_type m_id;
bool m_deleted : 1;
object_version_type m_version : 31;
diff --git a/include/osmium/osm/relation.hpp b/include/osmium/osm/relation.hpp
index 8c09680..2aa9caa 100644
--- a/include/osmium/osm/relation.hpp
+++ b/include/osmium/osm/relation.hpp
@@ -43,14 +43,11 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/item_type.hpp>
#include <osmium/osm/object.hpp>
#include <osmium/osm/types.hpp>
-#include <osmium/util/compatibility.hpp>
namespace osmium {
namespace builder {
- template <typename TDerived, typename T>
- class OSMObjectBuilder;
-
+ template <typename> class ObjectBuilder;
class RelationMemberListBuilder;
} // namespace builder
@@ -112,8 +109,7 @@ namespace osmium {
return m_ref;
}
- /// @deprecated Use set_ref() instead.
- OSMIUM_DEPRECATED RelationMember& ref(object_id_type ref) noexcept {
+ RelationMember& ref(object_id_type ref) noexcept {
m_ref = ref;
return *this;
}
@@ -153,18 +149,23 @@ namespace osmium {
public:
+ using size_type = size_t;
+
RelationMemberList() :
osmium::memory::Collection<RelationMember, osmium::item_type::relation_member_list>() {
}
+ size_type size() const noexcept {
+ return static_cast<size_type>(std::distance(begin(), end()));
+ }
+
}; // class RelationMemberList
static_assert(sizeof(RelationMemberList) % osmium::memory::align_bytes == 0, "Class osmium::RelationMemberList has wrong size to be aligned properly!");
class Relation : public OSMObject {
- template <typename TDerived, typename T>
- friend class osmium::builder::OSMObjectBuilder;
+ friend class osmium::builder::ObjectBuilder<osmium::Relation>;
Relation() noexcept :
OSMObject(sizeof(Relation), osmium::item_type::relation) {
diff --git a/include/osmium/osm/tag.hpp b/include/osmium/osm/tag.hpp
index e2537ce..cd2a913 100644
--- a/include/osmium/osm/tag.hpp
+++ b/include/osmium/osm/tag.hpp
@@ -86,14 +86,12 @@ namespace osmium {
}; // class Tag
- inline bool operator==(const Tag& lhs, const Tag& rhs) {
- return !std::strcmp(lhs.key(), rhs.key()) &&
- !std::strcmp(lhs.value(), rhs.value());
+ inline bool operator==(const Tag& a, const Tag& b) {
+ return !std::strcmp(a.key(), b.key()) && !std::strcmp(a.value(), b.value());
}
- inline bool operator<(const Tag& lhs, const Tag& rhs) {
- const auto c = std::strcmp(lhs.key(), rhs.key());
- return (c == 0 ? std::strcmp(lhs.value(), rhs.value()) : c) < 0;
+ inline bool operator<(const Tag& a, const Tag& b) {
+ return (!std::strcmp(a.key(), b.key()) && (std::strcmp(a.value(), b.value()) < 0)) || (std::strcmp(a.key(), b.key()) < 0);
}
/**
@@ -114,11 +112,20 @@ namespace osmium {
public:
+ using size_type = size_t;
+
TagList() :
osmium::memory::Collection<Tag, osmium::item_type::tag_list>() {
}
/**
+ * Returns the number of tags in this tag list.
+ */
+ size_type size() const noexcept {
+ return static_cast<size_type>(std::distance(begin(), end()));
+ }
+
+ /**
* Get tag value for the given tag key. If the key is not set, returns
* the default_value.
*
diff --git a/include/osmium/osm/way.hpp b/include/osmium/osm/way.hpp
index e4415ef..f6713fe 100644
--- a/include/osmium/osm/way.hpp
+++ b/include/osmium/osm/way.hpp
@@ -44,8 +44,7 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
namespace builder {
- template <typename TDerived, typename T>
- class OSMObjectBuilder;
+ template <typename T> class ObjectBuilder;
} // namespace builder
/**
@@ -67,8 +66,7 @@ namespace osmium {
class Way : public OSMObject {
- template <typename TDerived, typename T>
- friend class osmium::builder::OSMObjectBuilder;
+ friend class osmium::builder::ObjectBuilder<osmium::Way>;
Way() noexcept :
OSMObject(sizeof(Way), osmium::item_type::way) {
diff --git a/include/osmium/relations/collector.hpp b/include/osmium/relations/collector.hpp
index 53f6de9..b8455b4 100644
--- a/include/osmium/relations/collector.hpp
+++ b/include/osmium/relations/collector.hpp
@@ -40,7 +40,6 @@ DEALINGS IN THE SOFTWARE.
#include <functional>
#include <iomanip>
#include <iostream>
-#include <utility>
#include <vector>
#include <osmium/osm/item_type.hpp>
@@ -354,7 +353,7 @@ namespace osmium {
member_meta(member.type()).emplace_back(member.ref(), m_relations.size(), n);
relation_meta.increment_need_members();
} else {
- member.set_ref(0); // set member id to zero to indicate we are not interested
+ member.ref(0); // set member id to zero to indicate we are not interested
}
++n;
}
@@ -495,65 +494,12 @@ namespace osmium {
return m_members_buffer;
}
- /**
- * Is the given member available in the members buffer?
- *
- * If you also need the offset of the object, use
- * get_availability_and_offset() instead, it is more efficient
- * that way.
- *
- * @param type Item type
- * @param id Object Id
- * @returns True if the object is available, false otherwise.
- */
- bool is_available(osmium::item_type type, osmium::object_id_type id) {
- const auto range = find_member_meta(type, id);
- assert(!range.empty());
- return range.begin()->is_available();
- }
-
- /**
- * Get offset of a member in the members buffer.
- *
- * @pre The member must be available. If you are not sure, call
- * get_availability_and_offset() instead.
- * @param type Item type
- * @param id Object Id
- * @returns The offset of the object in the members buffer.
- */
size_t get_offset(osmium::item_type type, osmium::object_id_type id) {
const auto range = find_member_meta(type, id);
assert(!range.empty());
- assert(range.begin()->is_available());
return range.begin()->buffer_offset();
}
- /**
- * Checks whether a member is available in the members buffer
- * and returns its offset.
- *
- * If the member is not available, the boolean returned as the
- * first element in the pair is false. In that case the offset
- * in the second element is undefined.
- *
- * If the member is available, the boolean returned as the first
- * element in the pair is true and the second element of the
- * pair contains the offset into the members buffer.
- *
- * @param type Item type
- * @param id Object Id
- * @returns Pair of bool (showing availability) and the offset.
- */
- std::pair<bool, size_t> get_availability_and_offset(osmium::item_type type, osmium::object_id_type id) {
- const auto range = find_member_meta(type, id);
- assert(!range.empty());
- if (range.begin()->is_available()) {
- return std::make_pair(true, range.begin()->buffer_offset());
- } else {
- return std::make_pair(false, 0);
- }
- }
-
template <typename TIter>
void read_relations(TIter begin, TIter end) {
HandlerPass1 handler(*static_cast<TCollector*>(this));
@@ -579,7 +525,7 @@ namespace osmium {
/**
* Decide whether to purge removed members and then do it.
*
- * Currently the purging is done every 10000 calls.
+ * Currently the purging is done every thousand calls.
* This could probably be improved upon.
*/
void possibly_purge_removed_members() {
diff --git a/include/osmium/relations/detail/member_meta.hpp b/include/osmium/relations/detail/member_meta.hpp
index 7624a60..b28dca1 100644
--- a/include/osmium/relations/detail/member_meta.hpp
+++ b/include/osmium/relations/detail/member_meta.hpp
@@ -35,7 +35,6 @@ DEALINGS IN THE SOFTWARE.
#include <cstddef>
#include <iosfwd>
-#include <limits>
#include <osmium/osm/types.hpp>
@@ -72,44 +71,24 @@ namespace osmium {
/**
* Offset in the buffer where the object is stored.
- *
- * The default value is one that will never be valid, so it is
- * easier to catch problems.
*/
- size_t m_buffer_offset = std::numeric_limits<size_t>::max();
+ size_t m_buffer_offset { 0 };
- /**
- * Has this member been found in the input data.
- */
- bool m_available = false;
-
- /**
- * Marks this member as removed. It can not be used any more.
- */
bool m_removed = false;
public:
/**
- * Create new MemberMeta.
+ * Create new MemberMeta. The variant with zeros for relation_pos and
+ * member_pos is used to create dummy MemberMeta that can be compared
+ * to the MemberMeta in the vectors using the equal_range algorithm.
*/
- explicit MemberMeta(osmium::object_id_type member_id, size_t relation_pos, size_t member_pos) noexcept :
+ explicit MemberMeta(osmium::object_id_type member_id, size_t relation_pos=0, size_t member_pos=0) noexcept :
m_member_id(member_id),
m_relation_pos(relation_pos),
m_member_pos(member_pos) {
}
- /**
- * Create new MemberMeta. This constructor is used to create
- * dummy MemberMeta objects that can be compared to the
- * MemberMetas in a vector using the equal_range algorithm.
- */
- explicit MemberMeta(osmium::object_id_type member_id) noexcept :
- m_member_id(member_id),
- m_relation_pos(0),
- m_member_pos(0) {
- }
-
osmium::object_id_type member_id() const noexcept {
return m_member_id;
}
@@ -128,11 +107,6 @@ namespace osmium {
void set_buffer_offset(size_t offset) noexcept {
m_buffer_offset = offset;
- m_available = true;
- }
-
- bool is_available() const noexcept {
- return m_available;
}
bool removed() const noexcept {
@@ -150,8 +124,8 @@ namespace osmium {
* Used to sort a vector of MemberMeta objects and to later find
* them using binary search.
*/
- inline bool operator<(const MemberMeta& lhs, const MemberMeta& rhs) noexcept {
- return lhs.member_id() < rhs.member_id();
+ inline bool operator<(const MemberMeta& a, const MemberMeta& b) noexcept {
+ return a.member_id() < b.member_id();
}
template <typename TChar, typename TTraits>
diff --git a/include/osmium/thread/queue.hpp b/include/osmium/thread/queue.hpp
index 5ae9108..6f4f7b1 100644
--- a/include/osmium/thread/queue.hpp
+++ b/include/osmium/thread/queue.hpp
@@ -51,7 +51,7 @@ namespace osmium {
namespace thread {
- static const std::chrono::milliseconds max_wait{10};
+ static const std::chrono::milliseconds full_queue_sleep_duration { 10 }; // XXX
/**
* A thread-safe queue.
@@ -70,12 +70,9 @@ namespace osmium {
std::queue<T> m_queue;
- /// Used to signal consumers when data is available in the queue.
+ /// Used to signal readers when data is available in the queue.
std::condition_variable m_data_available;
- /// Used to signal producers when queue is not full.
- std::condition_variable m_space_available;
-
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
/// The largest size the queue has been so far.
size_t m_largest_size;
@@ -112,8 +109,7 @@ namespace osmium {
m_name(name),
m_mutex(),
m_queue(),
- m_data_available(),
- m_space_available()
+ m_data_available()
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
,
m_largest_size(0),
@@ -127,20 +123,13 @@ namespace osmium {
~Queue() {
#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 in " << m_push_counter
- << " push() calls and was empty " << m_empty_counter
- << " times in " << m_pop_counter
- << " pop() calls\n";
+ std::cerr << "queue '" << m_name << "' with max_size=" << m_max_size << " had largest size " << m_largest_size << " and was full " << m_full_counter << " times in " << m_push_counter << " push() calls and was empty " << m_empty_counter << " times in " << m_pop_counter << " pop() calls\n";
#endif
}
/**
- * Push an element onto the queue. If the queue has a max size,
- * this call will block if the queue is full.
+ * Push an element onto the queue. If the queue has a max size, this
+ * call will block if the queue is full.
*/
void push(T value) {
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
@@ -148,16 +137,13 @@ namespace osmium {
#endif
if (m_max_size) {
while (size() >= m_max_size) {
- std::unique_lock<std::mutex> lock{m_mutex};
- m_space_available.wait_for(lock, max_wait, [this] {
- return m_queue.size() < m_max_size;
- });
+ std::this_thread::sleep_for(full_queue_sleep_duration);
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
++m_full_counter;
#endif
}
}
- std::lock_guard<std::mutex> lock{m_mutex};
+ std::lock_guard<std::mutex> lock(m_mutex);
m_queue.push(std::move(value));
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
if (m_largest_size < m_queue.size()) {
@@ -171,7 +157,7 @@ namespace osmium {
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
++m_pop_counter;
#endif
- std::unique_lock<std::mutex> lock{m_mutex};
+ std::unique_lock<std::mutex> lock(m_mutex);
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
if (m_queue.empty()) {
++m_empty_counter;
@@ -183,10 +169,6 @@ namespace osmium {
if (!m_queue.empty()) {
value = std::move(m_queue.front());
m_queue.pop();
- lock.unlock();
- if (m_max_size) {
- m_space_available.notify_one();
- }
}
}
@@ -194,30 +176,25 @@ namespace osmium {
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
++m_pop_counter;
#endif
- {
- std::lock_guard<std::mutex> lock{m_mutex};
- if (m_queue.empty()) {
+ std::lock_guard<std::mutex> lock(m_mutex);
+ if (m_queue.empty()) {
#ifdef OSMIUM_DEBUG_QUEUE_SIZE
- ++m_empty_counter;
+ ++m_empty_counter;
#endif
- return false;
- }
- value = std::move(m_queue.front());
- m_queue.pop();
- }
- if (m_max_size) {
- m_space_available.notify_one();
+ return false;
}
+ value = std::move(m_queue.front());
+ m_queue.pop();
return true;
}
bool empty() const {
- std::lock_guard<std::mutex> lock{m_mutex};
+ std::lock_guard<std::mutex> lock(m_mutex);
return m_queue.empty();
}
size_t size() const {
- std::lock_guard<std::mutex> lock{m_mutex};
+ std::lock_guard<std::mutex> lock(m_mutex);
return m_queue.size();
}
diff --git a/include/osmium/util/progress_bar.hpp b/include/osmium/util/progress_bar.hpp
index 0e528fc..814aa2c 100644
--- a/include/osmium/util/progress_bar.hpp
+++ b/include/osmium/util/progress_bar.hpp
@@ -172,18 +172,6 @@ namespace osmium {
}
}
- /**
- * Removes the progress bar. Call this before doing any other output.
- * The next time update() is called, the progress bar will be visible
- * again.
- */
- void remove() {
- if (m_enable) {
- std::cerr << spc() << " \r";
- m_prev_percent = 100 + 1;
- }
- }
-
}; // class ProgressBar
} // namespace osmium
diff --git a/include/osmium/version.hpp b/include/osmium/version.hpp
index 09c5762..6f3b0a3 100644
--- a/include/osmium/version.hpp
+++ b/include/osmium/version.hpp
@@ -34,9 +34,9 @@ DEALINGS IN THE SOFTWARE.
*/
#define LIBOSMIUM_VERSION_MAJOR 2
-#define LIBOSMIUM_VERSION_MINOR 10
+#define LIBOSMIUM_VERSION_MINOR 9
#define LIBOSMIUM_VERSION_PATCH 0
-#define LIBOSMIUM_VERSION_STRING "2.10.0"
+#define LIBOSMIUM_VERSION_STRING "2.9.0"
#endif // OSMIUM_VERSION_HPP
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 051574e..6230cde 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -112,6 +112,12 @@ if(NOT Threads_FOUND)
set(Threads_FOUND FALSE)
endif()
+if(GEOS_FOUND AND PROJ_FOUND)
+ set(GEOS_AND_PROJ_FOUND TRUE)
+else()
+ set(GEOS_AND_PROJ_FOUND FALSE)
+endif()
+
#-----------------------------------------------------------------------------
#
@@ -121,45 +127,45 @@ endif()
add_unit_test(area test_area_id)
add_unit_test(area test_node_ref_segment)
-add_unit_test(osm test_area)
-add_unit_test(osm test_box)
-add_unit_test(osm test_changeset)
-add_unit_test(osm test_crc)
-add_unit_test(osm test_entity_bits)
-add_unit_test(osm test_location)
-add_unit_test(osm test_node)
-add_unit_test(osm test_node_ref)
-add_unit_test(osm test_object_comparisons)
-add_unit_test(osm test_relation)
-add_unit_test(osm test_timestamp)
-add_unit_test(osm test_types_from_string)
-add_unit_test(osm test_way)
-
-add_unit_test(memory test_buffer_basics)
-add_unit_test(memory test_buffer_node)
-add_unit_test(memory test_buffer_purge)
+add_unit_test(basic test_area)
+add_unit_test(basic test_box)
+add_unit_test(basic test_changeset)
+add_unit_test(basic test_crc)
+add_unit_test(basic test_entity_bits)
+add_unit_test(basic test_location)
+add_unit_test(basic test_node)
+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_basics)
+add_unit_test(buffer test_buffer_node)
+add_unit_test(buffer test_buffer_purge)
add_unit_test(builder test_attr)
-add_unit_test(builder test_object_builder)
+
+add_unit_test(geom test_factory_with_projection
+ ENABLE_IF ${GEOS_AND_PROJ_FOUND}
+ LIBS ${GEOS_LIBRARY} ${PROJ_LIBRARY})
add_unit_test(geom test_crs ENABLE_IF ${PROJ_FOUND} LIBS ${PROJ_LIBRARY})
add_unit_test(geom test_exception)
-add_unit_test(geom test_factory_with_projection ENABLE_IF ${PROJ_FOUND} LIBS ${PROJ_LIBRARY})
add_unit_test(geom test_geojson)
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 ENABLE_IF ${GDAL_FOUND} LIBS ${GDAL_LIBRARY})
-add_unit_test(geom test_ogr_wkb 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_tile ENABLE_IF ${GEOS_FOUND})
add_unit_test(geom test_wkb)
add_unit_test(geom test_wkt)
-add_unit_test(index test_id_set)
add_unit_test(index test_id_to_location ENABLE_IF ${SPARSEHASH_FOUND})
add_unit_test(index test_file_based_index)
-add_unit_test(io test_compression_factory)
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 LIBS "${OSMIUM_XML_LIBRARIES};${OSMIUM_PBF_LIBRARIES}")
diff --git a/test/data-tests/testdata-xml.cpp b/test/data-tests/testdata-xml.cpp
index eb984f8..0d2739a 100644
--- a/test/data-tests/testdata-xml.cpp
+++ b/test/data-tests/testdata-xml.cpp
@@ -83,7 +83,7 @@ header_buffer_type parse_xml(std::string input) {
osmium::io::detail::add_to_queue(input_queue, std::move(input));
osmium::io::detail::add_to_queue(input_queue, std::string{});
- osmium::io::detail::XMLParser parser{input_queue, output_queue, header_promise, osmium::io::detail::reader_options{}};
+ osmium::io::detail::XMLParser parser{input_queue, output_queue, header_promise, osmium::osm_entity_bits::all};
parser.parse();
header_buffer_type result;
diff --git a/test/examples/CMakeLists.txt b/test/examples/CMakeLists.txt
deleted file mode 100644
index 90bf76e..0000000
--- a/test/examples/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-#-----------------------------------------------------------------------------
-#
-# CMake Config
-#
-# Libosmium example tests
-#
-#-----------------------------------------------------------------------------
-
-message(STATUS "Configuring example tests")
-
-file(GLOB _dirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/t/*)
-
-foreach(_dir ${_dirs})
- message(STATUS " adding test: ${_dir}")
- add_subdirectory("${_dir}")
-endforeach()
-
-message(STATUS "Configuring example tests - done")
-
-
-#-----------------------------------------------------------------------------
diff --git a/test/examples/t/pub_names/CMakeLists.txt b/test/examples/t/pub_names/CMakeLists.txt
deleted file mode 100644
index 9a68ae8..0000000
--- a/test/examples/t/pub_names/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-
-add_test(NAME examples_pub_names
- COMMAND osmium_pub_names ${CMAKE_CURRENT_SOURCE_DIR}/pubs.osm)
-
-set_tests_properties(examples_pub_names PROPERTIES
- PASS_REGULAR_EXPRESSION "^Im Holze\n$")
-
diff --git a/test/examples/t/pub_names/pubs.osm b/test/examples/t/pub_names/pubs.osm
deleted file mode 100644
index ee54226..0000000
--- a/test/examples/t/pub_names/pubs.osm
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<osm version="0.6">
- <node id="167199652" version="3" timestamp="2010-12-27T13:15:02Z" uid="57645" user="KartoGrapHiti" changeset="6777507" lat="53.0526516" lon="8.8919477">
- <tag k="amenity" v="pub"/>
- <tag k="name" v="Im Holze"/>
- </node>
-</osm>
diff --git a/test/examples/t/road_length/CMakeLists.txt b/test/examples/t/road_length/CMakeLists.txt
deleted file mode 100644
index 6323f07..0000000
--- a/test/examples/t/road_length/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-
-add_test(NAME examples_road_length
- COMMAND osmium_road_length ${CMAKE_CURRENT_SOURCE_DIR}/road.osm)
-
-set_tests_properties(examples_road_length PROPERTIES
- PASS_REGULAR_EXPRESSION "^Length: 0\\.405.*km\n$"
-)
-
diff --git a/test/examples/t/road_length/road.osm b/test/examples/t/road_length/road.osm
deleted file mode 100644
index 934ef46..0000000
--- a/test/examples/t/road_length/road.osm
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<osm version="0.6" generator="CGImap 0.3.3 (31041 thorn-01.openstreetmap.org)" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
- <node id="5599384" visible="true" version="5" changeset="829716" timestamp="2009-03-18T17:16:26Z" user="burts" uid="97529" lat="51.0271601" lon="13.7252197"/>
- <node id="250384970" visible="true" version="3" changeset="855544" timestamp="2009-01-30T21:58:37Z" user="saftl" uid="7989" lat="51.0288568" lon="13.7248159">
- <tag k="created_by" v="JOSM"/>
- </node>
- <node id="250996316" visible="true" version="5" changeset="838711" timestamp="2009-03-21T13:10:39Z" user="burts" uid="97529" lat="51.0274683" lon="13.7251464"/>
- <node id="250996321" visible="true" version="3" changeset="855544" timestamp="2009-01-30T21:59:14Z" user="saftl" uid="7989" lat="51.0284283" lon="13.7249179">
- <tag k="created_by" v="JOSM"/>
- </node>
- <node id="252587568" visible="true" version="3" changeset="855544" timestamp="2009-01-30T21:58:45Z" user="saftl" uid="7989" lat="51.0275477" lon="13.7251275">
- <tag k="created_by" v="JOSM"/>
- </node>
- <node id="5599381" visible="true" version="6" changeset="15768585" timestamp="2013-04-18T01:20:26Z" user="Wolle DD" uid="1161559" lat="51.0307642" lon="13.7243263"/>
- <node id="1122039499" visible="true" version="2" changeset="26063898" timestamp="2014-10-14T04:09:11Z" user="Seandebasti" uid="550560" lat="51.0285248" lon="13.7248970"/>
- <node id="1122039521" visible="true" version="2" changeset="12753110" timestamp="2012-08-16T17:03:47Z" user="TEAM_CN_TUD" uid="716608" lat="51.0277456" lon="13.7250806"/>
- <node id="5599382" visible="true" version="6" changeset="8191054" timestamp="2011-05-19T16:19:51Z" user="stw1701" uid="102899" lat="51.0297991" lon="13.7245892"/>
- <node id="1299329303" visible="true" version="1" changeset="8242335" timestamp="2011-05-25T07:46:01Z" user="bigbug21" uid="15748" lat="51.0290875" lon="13.7247628"/>
- <node id="1868844753" visible="true" version="2" changeset="13260925" timestamp="2012-09-26T15:26:31Z" user="TEAM_CN_TUD" uid="716608" lat="51.0289617" lon="13.7247917"/>
- <node id="1868844765" visible="true" version="2" changeset="13260925" timestamp="2012-09-26T15:26:31Z" user="TEAM_CN_TUD" uid="716608" lat="51.0292872" lon="13.7247140"/>
- <node id="1868844782" visible="true" version="2" changeset="13260925" timestamp="2012-09-26T15:26:31Z" user="TEAM_CN_TUD" uid="716608" lat="51.0295717" lon="13.7246429"/>
- <node id="1922091528" visible="true" version="2" changeset="13260925" timestamp="2012-09-26T15:26:31Z" user="TEAM_CN_TUD" uid="716608" lat="51.0281700" lon="13.7249813"/>
- <node id="1953249124" visible="true" version="1" changeset="13418280" timestamp="2012-10-08T20:18:35Z" user="TEAM_CN_TUD" uid="716608" lat="51.0292437" lon="13.7247246"/>
- <node id="2015120752" visible="true" version="1" changeset="13883494" timestamp="2012-11-15T14:22:31Z" user="TEAM_CN_TUD" uid="716608" lat="51.0293536" lon="13.7246974"/>
- <node id="2056871900" visible="true" version="1" changeset="14207491" timestamp="2012-12-09T00:03:11Z" user="bigbug21" uid="15748" lat="51.0305821" lon="13.7243895"/>
- <node id="2458246647" visible="true" version="1" changeset="17836591" timestamp="2013-09-14T17:05:06Z" user="bigbug21" uid="15748" lat="51.0295979" lon="13.7246367"/>
- <node id="250384969" visible="true" version="4" changeset="17857555" timestamp="2013-09-15T20:17:55Z" user="4b696d" uid="1420318" lat="51.0282021" lon="13.7249734"/>
- <node id="3128723784" visible="true" version="1" changeset="26063898" timestamp="2014-10-14T04:09:07Z" user="Seandebasti" uid="550560" lat="51.0281018" lon="13.7249973"/>
- <way id="4428564" visible="true" version="21" changeset="26063898" timestamp="2014-10-14T04:09:13Z" user="Seandebasti" uid="550560">
- <nd ref="5599381"/>
- <nd ref="2056871900"/>
- <nd ref="5599382"/>
- <nd ref="2458246647"/>
- <nd ref="1868844782"/>
- <nd ref="2015120752"/>
- <nd ref="1868844765"/>
- <nd ref="1953249124"/>
- <nd ref="1299329303"/>
- <nd ref="1868844753"/>
- <nd ref="250384970"/>
- <nd ref="1122039499"/>
- <nd ref="250996321"/>
- <nd ref="250384969"/>
- <nd ref="1922091528"/>
- <nd ref="3128723784"/>
- <nd ref="1122039521"/>
- <nd ref="252587568"/>
- <nd ref="250996316"/>
- <nd ref="5599384"/>
- <tag k="highway" v="residential"/>
- <tag k="lit" v="yes"/>
- <tag k="maxspeed" v="30"/>
- <tag k="name" v="Helmholtzstraße"/>
- <tag k="postal_code" v="01069"/>
- <tag k="sidewalk" v="both"/>
- <tag k="smoothness" v="good"/>
- <tag k="surface" v="asphalt"/>
- </way>
-</osm>
\ No newline at end of file
diff --git a/test/include/catch.hpp b/test/include/catch.hpp
index 2e6fe8d..879fc5b 100644
--- a/test/include/catch.hpp
+++ b/test/include/catch.hpp
@@ -1,6 +1,6 @@
/*
- * Catch v1.5.8
- * Generated: 2016-10-26 12:07:30.938259
+ * Catch v1.5.6
+ * Generated: 2016-06-09 19:20:41.460328
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
@@ -3223,11 +3223,10 @@ namespace Catch {
bool matches( TestCaseInfo const& testCase ) const {
// All patterns in a filter must match for the filter to be a match
- for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) {
+ for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
if( !(*it)->matches( testCase ) )
return false;
- }
- return true;
+ return true;
}
};
@@ -4720,11 +4719,8 @@ namespace Catch {
std::string line;
while( std::getline( f, line ) ) {
line = trim(line);
- if( !line.empty() && !startsWith( line, "#" ) ) {
- if( !startsWith( line, "\"" ) )
- line = "\"" + line + "\"";
- addTestOrTags( config, line + "," );
- }
+ if( !line.empty() && !startsWith( line, "#" ) )
+ addTestOrTags( config, "\"" + line + "\"," );
}
}
@@ -5372,10 +5368,7 @@ namespace Catch {
++it ) {
matchedTests++;
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
- if( startsWith( testCaseInfo.name, "#" ) )
- Catch::cout() << "\"" << testCaseInfo.name << "\"" << std::endl;
- else
- Catch::cout() << testCaseInfo.name << std::endl;
+ Catch::cout() << testCaseInfo.name << std::endl;
}
return matchedTests;
}
@@ -6461,7 +6454,7 @@ namespace Catch {
namespace Catch {
struct RandomNumberGenerator {
- typedef std::ptrdiff_t result_type;
+ typedef int result_type;
result_type operator()( result_type n ) const { return std::rand() % n; }
@@ -7578,7 +7571,7 @@ namespace Catch {
return os;
}
- Version libraryVersion( 1, 5, 8, "", 0 );
+ Version libraryVersion( 1, 5, 6, "", 0 );
}
@@ -7809,11 +7802,8 @@ namespace Catch {
bool contains( std::string const& s, std::string const& infix ) {
return s.find( infix ) != std::string::npos;
}
- char toLowerCh(char c) {
- return static_cast<char>( ::tolower( c ) );
- }
void toLowerInPlace( std::string& s ) {
- std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
+ std::transform( s.begin(), s.end(), s.begin(), ::tolower );
}
std::string toLower( std::string const& s ) {
std::string lc = s;
@@ -8961,10 +8951,9 @@ namespace Catch {
break;
default:
- // Escape control chars - based on contribution by @espenalb in PR #465 and
- // by @mrpi PR #588
+ // Escape control chars - based on contribution by @espenalb in PR #465
if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
- os << "&#x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>( c ) << ';';
+ os << "&#x" << std::uppercase << std::hex << static_cast<int>( c );
else
os << c;
}
@@ -9019,20 +9008,13 @@ namespace Catch {
: m_tagIsOpen( false ),
m_needsNewline( false ),
m_os( &Catch::cout() )
- {
- // We encode control characters, which requires
- // XML 1.1
- // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
- *m_os << "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
- }
+ {}
XmlWriter( std::ostream& os )
: m_tagIsOpen( false ),
m_needsNewline( false ),
m_os( &os )
- {
- *m_os << "<?xml version=\"1.1\" encoding=\"UTF-8\"?>\n";
- }
+ {}
~XmlWriter() {
while( !m_tags.empty() )
@@ -9199,7 +9181,7 @@ namespace Catch {
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
StreamingReporterBase::testCaseStarting(testInfo);
- m_xml.startElement( "TestCase" ).writeAttribute( "name", testInfo.name );
+ m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
if ( m_config->showDurations() == ShowDurations::Always )
m_testCaseTimer.start();
@@ -9261,7 +9243,7 @@ namespace Catch {
.writeText( assertionResult.getMessage() );
break;
case ResultWas::FatalErrorCondition:
- m_xml.scopedElement( "FatalErrorCondition" )
+ m_xml.scopedElement( "Fatal Error Condition" )
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
.writeAttribute( "line", assertionResult.getSourceInfo().line )
.writeText( assertionResult.getMessage() );
diff --git a/test/t/osm/test_area.cpp b/test/t/basic/test_area.cpp
similarity index 100%
rename from test/t/osm/test_area.cpp
rename to test/t/basic/test_area.cpp
diff --git a/test/t/osm/test_box.cpp b/test/t/basic/test_box.cpp
similarity index 100%
rename from test/t/osm/test_box.cpp
rename to test/t/basic/test_box.cpp
diff --git a/test/t/osm/test_changeset.cpp b/test/t/basic/test_changeset.cpp
similarity index 73%
rename from test/t/osm/test_changeset.cpp
rename to test/t/basic/test_changeset.cpp
index 9be8fbb..36c4778 100644
--- a/test/t/osm/test_changeset.cpp
+++ b/test/t/basic/test_changeset.cpp
@@ -9,7 +9,7 @@
using namespace osmium::builder::attr;
TEST_CASE("Build changeset") {
- osmium::memory::Buffer buffer{10 * 1000};
+ osmium::memory::Buffer buffer(10 * 1000);
osmium::builder::add_changeset(buffer,
_cid(42),
@@ -88,57 +88,58 @@ TEST_CASE("Build changeset") {
}
TEST_CASE("Create changeset without helper") {
- osmium::memory::Buffer buffer{10 * 1000};
+ osmium::memory::Buffer buffer(10 * 1000);
+ osmium::builder::ChangesetBuilder builder(buffer);
+
+ osmium::Changeset& cs1 = builder.object();
+ cs1.set_id(42)
+ .set_created_at(100)
+ .set_closed_at(200)
+ .set_num_changes(7)
+ .set_num_comments(2)
+ .set_uid(9);
+
+ builder.add_user("user");
{
- osmium::builder::ChangesetBuilder builder{buffer};
-
- builder.set_id(42)
- .set_created_at(100)
- .set_closed_at(200)
- .set_num_changes(7)
- .set_num_comments(2)
- .set_uid(9)
- .set_user("user");
-
- {
- osmium::builder::TagListBuilder tl_builder{builder};
- tl_builder.add_tag("key1", "val1");
- tl_builder.add_tag("key2", "val2");
- }
-
- osmium::builder::ChangesetDiscussionBuilder disc_builder{builder};
+ osmium::builder::TagListBuilder tl_builder(buffer, &builder);
+ tl_builder.add_tag("key1", "val1");
+ tl_builder.add_tag("key2", "val2");
+ }
+
+ {
+ osmium::builder::ChangesetDiscussionBuilder disc_builder(buffer, &builder);
disc_builder.add_comment(osmium::Timestamp(300), 10, "user2");
disc_builder.add_comment_text("foo");
disc_builder.add_comment(osmium::Timestamp(400), 9, "user");
disc_builder.add_comment_text("bar");
}
- const auto& cs = buffer.get<osmium::Changeset>(buffer.commit());
+ buffer.commit();
- REQUIRE(42 == cs.id());
- REQUIRE(9 == cs.uid());
- REQUIRE(7 == cs.num_changes());
- REQUIRE(2 == cs.num_comments());
- REQUIRE(true == cs.closed());
- REQUIRE(osmium::Timestamp(100) == cs.created_at());
- REQUIRE(osmium::Timestamp(200) == cs.closed_at());
- REQUIRE(2 == cs.tags().size());
- REQUIRE(std::string("user") == cs.user());
+ REQUIRE(42 == cs1.id());
+ REQUIRE(9 == cs1.uid());
+ REQUIRE(7 == cs1.num_changes());
+ REQUIRE(2 == cs1.num_comments());
+ REQUIRE(true == cs1.closed());
+ REQUIRE(osmium::Timestamp(100) == cs1.created_at());
+ REQUIRE(osmium::Timestamp(200) == cs1.closed_at());
+ REQUIRE(2 == cs1.tags().size());
+ REQUIRE(std::string("user") == cs1.user());
- auto cit = cs.discussion().begin();
+ auto cit = cs1.discussion().begin();
- REQUIRE(cit != cs.discussion().end());
+ REQUIRE(cit != cs1.discussion().end());
REQUIRE(cit->date() == osmium::Timestamp(300));
REQUIRE(cit->uid() == 10);
REQUIRE(std::string("user2") == cit->user());
REQUIRE(std::string("foo") == cit->text());
- REQUIRE(++cit != cs.discussion().end());
+ REQUIRE(++cit != cs1.discussion().end());
REQUIRE(cit->date() == osmium::Timestamp(400));
REQUIRE(cit->uid() == 9);
REQUIRE(std::string("user") == cit->user());
REQUIRE(std::string("bar") == cit->text());
- REQUIRE(++cit == cs.discussion().end());
+ REQUIRE(++cit == cs1.discussion().end());
}
diff --git a/test/t/osm/test_crc.cpp b/test/t/basic/test_crc.cpp
similarity index 100%
rename from test/t/osm/test_crc.cpp
rename to test/t/basic/test_crc.cpp
diff --git a/test/t/basic/test_entity_bits.cpp b/test/t/basic/test_entity_bits.cpp
new file mode 100644
index 0000000..13de94b
--- /dev/null
+++ b/test/t/basic/test_entity_bits.cpp
@@ -0,0 +1,32 @@
+#include "catch.hpp"
+
+#include <osmium/osm/entity_bits.hpp>
+
+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));
+
+ 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);
+
+ 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);
+
+ REQUIRE(osmium::osm_entity_bits::nothing == osmium::osm_entity_bits::from_item_type(osmium::item_type::undefined));
+ 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/osm/test_location.cpp b/test/t/basic/test_location.cpp
similarity index 78%
rename from test/t/osm/test_location.cpp
rename to test/t/basic/test_location.cpp
index 7abf779..dc5b378 100644
--- a/test/t/osm/test_location.cpp
+++ b/test/t/basic/test_location.cpp
@@ -166,44 +166,41 @@ TEST_CASE("Location hash") {
}
}
-void C(const char* s, long v, const char* r = "") {
- std::string strm{"-"};
- strm += s;
- REQUIRE(std::atof(strm.c_str() + 1) == Approx( v / 10000000.0));
- REQUIRE(std::atof(strm.c_str() ) == Approx(-v / 10000000.0));
- const char* x = strm.c_str() + 1;
- const char** data = &x;
- REQUIRE(osmium::detail::string_to_location_coordinate(data) == v);
- REQUIRE(std::string{*data} == r);
- x = strm.c_str();
- data = &x;
- REQUIRE(osmium::detail::string_to_location_coordinate(data) == -v);
- REQUIRE(std::string{*data} == r);
-}
-
-void F(const char* s) {
- std::string strm{"-"};
- strm += s;
- const char* x = strm.c_str();
- const char** data = &x;
- REQUIRE_THROWS_AS(osmium::detail::string_to_location_coordinate(data), osmium::invalid_location);
- ++x;
- data = &x;
- REQUIRE_THROWS_AS(osmium::detail::string_to_location_coordinate(data), osmium::invalid_location);
-}
+#define CR(s, v, r) { \
+ const char* strm = "-" s; \
+ const char* strp = strm + 1; \
+ REQUIRE(std::atof(strp) == Approx( v / 10000000.0)); \
+ REQUIRE(std::atof(strm) == Approx(-v / 10000000.0)); \
+ const char** data = &strp; \
+ REQUIRE(osmium::detail::string_to_location_coordinate(data) == v); \
+ REQUIRE(std::string{*data} == r); \
+ data = &strm; \
+ REQUIRE(osmium::detail::string_to_location_coordinate(data) == -v); \
+ REQUIRE(std::string{*data} == r); \
+ }
+
+#define C(s, v) CR(s, v, "")
+
+#define F(s) { \
+ const char* strm = "-" s; \
+ const char* strp = strm + 1; \
+ const char** data = &strp; \
+ REQUIRE_THROWS_AS(osmium::detail::string_to_location_coordinate(data), osmium::invalid_location); \
+ data = &strm; \
+ REQUIRE_THROWS_AS(osmium::detail::string_to_location_coordinate(data), osmium::invalid_location); \
+ }
TEST_CASE("Parsing coordinates from strings") {
F("x");
F(".");
- F(".e2");
F("--");
F("");
F(" ");
F(" 123");
- C("123 ", 1230000000, " ");
- C("123x", 1230000000, "x");
- C("1.2x", 12000000, "x");
+ CR("123 ", 1230000000, " ");
+ CR("123x", 1230000000, "x");
+ CR("1.2x", 12000000, "x");
C("0", 0);
@@ -226,19 +223,14 @@ TEST_CASE("Parsing coordinates from strings") {
F("1234");
F("1234.");
F("12345678901234567890");
- F("1.1234568111111111111111111111111111111");
- F("112.34568111111111111111111111111111111");
C("0.", 0);
- C(".0", 0);
C("0.0", 0);
C("1.", 10000000);
C("1.0", 10000000);
C("1.2", 12000000);
C("0.1", 1000000);
- C(".1", 1000000);
C("0.01", 100000);
- C(".01", 100000);
C("0.001", 10000);
C("0.0001", 1000);
C("0.00001", 100);
@@ -259,24 +251,6 @@ TEST_CASE("Parsing coordinates from strings") {
C("179.99999999", 1800000000);
C("200.123", 2001230000);
- C("8.109E-4" , 8109);
- C("8.1090E-4" , 8109);
- C("8.10909E-4" , 8109);
- C("8.109095E-4" , 8109);
- C("8.1090959E-4" , 8109);
- C("8.10909598E-4" , 8109);
- C("8.109095988E-4" , 8109);
- C("8.1090959887E-4" , 8109);
- C("8.10909598870E-4" , 8109);
- C("8.109095988709E-4" , 8109);
- C("8.1090959887098E-4" , 8109);
- C("8.10909598870983E-4" , 8109);
- C("8.109095988709837E-4" , 8109);
- C("81.09095988709837E-4" , 81091);
- C("810.9095988709837E-4" , 810910);
- C(".8109095988709837E-4" , 811);
- C(".08109095988709837E-4" , 81);
-
C("1e2", 1000000000);
C("1e1", 100000000);
C("1e0", 10000000);
@@ -289,10 +263,8 @@ TEST_CASE("Parsing coordinates from strings") {
C("1e-7", 1);
C("1.0e2", 1000000000);
- C("1.e2", 1000000000);
C("1.1e1", 110000000);
C("0.1e1", 10000000);
- C(".1e1", 10000000);
C("1.2e0", 12000000);
C("1.9e-1", 1900000);
C("2.0e-2", 200000);
@@ -319,35 +291,32 @@ TEST_CASE("Parsing coordinates from strings") {
F("5.0e2");
F("3e2");
F("1e");
- F("1e-");
- F("1e1234567");
F("0.5e");
F("1e10");
- C("1e2 ", 1000000000, " ");
- C("1.1e2 ", 1100000000, " ");
- C("1.1e2x", 1100000000, "x");
- C("1.1e2:", 1100000000, ":");
+ CR("1e2 ", 1000000000, " ");
+ CR("1.1e2 ", 1100000000, " ");
+ CR("1.1e2x", 1100000000, "x");
+ CR("1.1e2:", 1100000000, ":");
}
-TEST_CASE("Writing zero coordinate into string") {
- std::string buffer;
- osmium::detail::append_location_coordinate_to_string(std::back_inserter(buffer), 0);
- REQUIRE(buffer == "0");
-}
+#undef C
+#undef CR
+#undef F
+
+#define CW(v, s) buffer.clear(); \
+ osmium::detail::append_location_coordinate_to_string(std::back_inserter(buffer), v); \
+ CHECK(buffer == s); \
+ buffer.clear(); \
+ osmium::detail::append_location_coordinate_to_string(std::back_inserter(buffer), -v); \
+ CHECK(buffer == "-" s);
-void CW(long v, const char* s) {
+TEST_CASE("Writing coordinates into string") {
std::string buffer;
- osmium::detail::append_location_coordinate_to_string(std::back_inserter(buffer), v);
- REQUIRE(buffer == s);
- buffer.clear();
- osmium::detail::append_location_coordinate_to_string(std::back_inserter(buffer), -v);
- REQUIRE(buffer[0] == '-');
- REQUIRE_FALSE(std::strcmp(buffer.c_str() + 1, s));
-}
+ osmium::detail::append_location_coordinate_to_string(std::back_inserter(buffer), 0);
+ CHECK(buffer == "0");
-TEST_CASE("Writing coordinate into string") {
CW( 10000000, "1");
CW( 90000000, "9");
CW( 100000000, "10");
@@ -369,6 +338,8 @@ TEST_CASE("Writing coordinate into string") {
CW(1799999999, "179.9999999");
}
+#undef CW
+
TEST_CASE("set lon/lat from string") {
osmium::Location loc;
loc.set_lon("1.2");
diff --git a/test/t/osm/test_node.cpp b/test/t/basic/test_node.cpp
similarity index 100%
rename from test/t/osm/test_node.cpp
rename to test/t/basic/test_node.cpp
diff --git a/test/t/osm/test_node_ref.cpp b/test/t/basic/test_node_ref.cpp
similarity index 100%
rename from test/t/osm/test_node_ref.cpp
rename to test/t/basic/test_node_ref.cpp
diff --git a/test/t/osm/test_object_comparisons.cpp b/test/t/basic/test_object_comparisons.cpp
similarity index 100%
rename from test/t/osm/test_object_comparisons.cpp
rename to test/t/basic/test_object_comparisons.cpp
diff --git a/test/t/osm/test_relation.cpp b/test/t/basic/test_relation.cpp
similarity index 100%
rename from test/t/osm/test_relation.cpp
rename to test/t/basic/test_relation.cpp
diff --git a/test/t/osm/test_timestamp.cpp b/test/t/basic/test_timestamp.cpp
similarity index 100%
rename from test/t/osm/test_timestamp.cpp
rename to test/t/basic/test_timestamp.cpp
diff --git a/test/t/osm/test_types_from_string.cpp b/test/t/basic/test_types_from_string.cpp
similarity index 100%
rename from test/t/osm/test_types_from_string.cpp
rename to test/t/basic/test_types_from_string.cpp
diff --git a/test/t/osm/test_way.cpp b/test/t/basic/test_way.cpp
similarity index 98%
rename from test/t/osm/test_way.cpp
rename to test/t/basic/test_way.cpp
index 21258a4..005ef30 100644
--- a/test/t/osm/test_way.cpp
+++ b/test/t/basic/test_way.cpp
@@ -68,7 +68,7 @@ TEST_CASE("build way with helpers") {
{
osmium::builder::WayBuilder builder(buffer);
- builder.set_user("username");
+ builder.add_user("username");
builder.add_tags({
{"amenity", "restaurant"},
{"name", "Zum goldenen Schwanen"}
diff --git a/test/t/memory/test_buffer_basics.cpp b/test/t/buffer/test_buffer_basics.cpp
similarity index 100%
rename from test/t/memory/test_buffer_basics.cpp
rename to test/t/buffer/test_buffer_basics.cpp
diff --git a/test/t/memory/test_buffer_node.cpp b/test/t/buffer/test_buffer_node.cpp
similarity index 50%
rename from test/t/memory/test_buffer_node.cpp
rename to test/t/buffer/test_buffer_node.cpp
index 040cbb8..ba2431b 100644
--- a/test/t/memory/test_buffer_node.cpp
+++ b/test/t/buffer/test_buffer_node.cpp
@@ -3,7 +3,7 @@
#include <osmium/builder/osm_object_builder.hpp>
#include <osmium/osm/node.hpp>
-void check_node_1(const osmium::Node& node) {
+void check_node_1(osmium::Node& node) {
REQUIRE(1 == node.id());
REQUIRE(3 == node.version());
REQUIRE(true == node.visible());
@@ -11,9 +11,9 @@ void check_node_1(const osmium::Node& node) {
REQUIRE(21 == node.uid());
REQUIRE(123 == uint32_t(node.timestamp()));
REQUIRE(osmium::Location(3.5, 4.7) == node.location());
- REQUIRE(std::string{"testuser"} == node.user());
+ REQUIRE(std::string("testuser") == node.user());
- for (const osmium::memory::Item& item : node) {
+ for (osmium::memory::Item& item : node) {
REQUIRE(osmium::item_type::tag_list == item.type());
}
@@ -22,7 +22,7 @@ void check_node_1(const osmium::Node& node) {
REQUIRE(0 == std::distance(node.tags().begin(), node.tags().end()));
}
-void check_node_2(const osmium::Node& node) {
+void check_node_2(osmium::Node& node) {
REQUIRE(2 == node.id());
REQUIRE(3 == node.version());
REQUIRE(true == node.visible());
@@ -30,9 +30,9 @@ void check_node_2(const osmium::Node& node) {
REQUIRE(21 == node.uid());
REQUIRE(123 == uint32_t(node.timestamp()));
REQUIRE(osmium::Location(3.5, 4.7) == node.location());
- REQUIRE(std::string{"testuser"} == node.user());
+ REQUIRE(std::string("testuser") == node.user());
- for (const osmium::memory::Item& item : node) {
+ for (osmium::memory::Item& item : node) {
REQUIRE(osmium::item_type::tag_list == item.type());
}
@@ -61,52 +61,60 @@ TEST_CASE("Node in Buffer") {
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);
SECTION("Add node to buffer") {
{
// add node 1
- osmium::builder::NodeBuilder node_builder{buffer};
-
- node_builder.set_id(1)
- .set_version(3)
- .set_visible(true)
- .set_changeset(333)
- .set_uid(21)
- .set_timestamp(123)
- .set_location(osmium::Location{3.5, 4.7})
- .set_user("testuser");
- }
+ 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));
- buffer.commit();
+ node_builder.add_user("testuser");
+
+ buffer.commit();
+ }
{
// add node 2
- osmium::builder::NodeBuilder node_builder{buffer};
-
- node_builder.set_id(2)
- .set_version(3)
- .set_visible(true)
- .set_changeset(333)
- .set_uid(21)
- .set_timestamp(123)
- .set_location(osmium::Location{3.5, 4.7})
- .set_user("testuser");
-
- osmium::builder::TagListBuilder tag_builder{node_builder};
- tag_builder.add_tag("amenity", "bank");
- tag_builder.add_tag("name", "OSM Savings");
- }
+ 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 (const osmium::memory::Item& item : buffer) {
+ for (osmium::memory::Item& item : buffer) {
REQUIRE(osmium::item_type::node == item.type());
- const osmium::Node& node = static_cast<const osmium::Node&>(item);
+ osmium::Node& node = static_cast<osmium::Node&>(item);
switch (item_no) {
case 0:
@@ -129,21 +137,24 @@ TEST_CASE("Node in Buffer") {
{
// add node 1
- osmium::builder::NodeBuilder node_builder{buffer};
-
- node_builder.set_id(1)
- .set_version(3)
- .set_visible(true)
- .set_changeset(333)
- .set_uid(21)
- .set_timestamp(123)
- .set_location(osmium::Location{3.5, 4.7})
- .set_user("testuser");
- }
+ osmium::builder::NodeBuilder node_builder(buffer);
+ osmium::Node& node = node_builder.object();
+ REQUIRE(osmium::item_type::node == node.type());
- buffer.commit();
+ 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));
- osmium::memory::Buffer buffer2{buffer_size, osmium::memory::Buffer::auto_grow::yes};
+ node_builder.add_user("testuser");
+
+ buffer.commit();
+ }
+
+ osmium::memory::Buffer buffer2(buffer_size, osmium::memory::Buffer::auto_grow::yes);
buffer2.add_buffer(buffer);
buffer2.commit();
@@ -158,21 +169,24 @@ TEST_CASE("Node in Buffer") {
{
// add node 1
- osmium::builder::NodeBuilder node_builder{buffer};
-
- node_builder.set_id(1)
- .set_version(3)
- .set_visible(true)
- .set_changeset(333)
- .set_uid(21)
- .set_timestamp(123)
- .set_location(osmium::Location{3.5, 4.7})
- .set_user("testuser");
- }
+ osmium::builder::NodeBuilder node_builder(buffer);
+ osmium::Node& node = node_builder.object();
+ REQUIRE(osmium::item_type::node == node.type());
- buffer.commit();
+ 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::memory::Buffer buffer2{buffer_size, osmium::memory::Buffer::auto_grow::yes};
+ osmium::memory::Buffer buffer2(buffer_size, osmium::memory::Buffer::auto_grow::yes);
std::copy(buffer.begin(), buffer.end(), std::back_inserter(buffer2));
diff --git a/test/t/memory/test_buffer_purge.cpp b/test/t/buffer/test_buffer_purge.cpp
similarity index 60%
rename from test/t/memory/test_buffer_purge.cpp
rename to test/t/buffer/test_buffer_purge.cpp
index e61e08d..a72db1b 100644
--- a/test/t/memory/test_buffer_purge.cpp
+++ b/test/t/buffer/test_buffer_purge.cpp
@@ -17,9 +17,9 @@ struct CallbackClass {
TEST_CASE("Purge data from buffer") {
constexpr size_t buffer_size = 10000;
- osmium::memory::Buffer buffer{buffer_size};
SECTION("purge empty buffer") {
+ osmium::memory::Buffer buffer(buffer_size);
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 0);
CallbackClass callback;
@@ -30,13 +30,15 @@ TEST_CASE("Purge data from buffer") {
}
SECTION("purge buffer with one object but nothing to delete") {
+ osmium::memory::Buffer buffer(buffer_size);
+
{
- osmium::builder::NodeBuilder node_builder{buffer};
- node_builder.set_user("testuser");
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("testuser");
}
buffer.commit();
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1);
- const size_t committed = buffer.committed();
+ size_t committed = buffer.committed();
CallbackClass callback;
buffer.purge_removed(&callback);
@@ -47,10 +49,12 @@ TEST_CASE("Purge data from buffer") {
}
SECTION("purge buffer with one object which gets deleted") {
+ osmium::memory::Buffer buffer(buffer_size);
+
{
- osmium::builder::NodeBuilder node_builder{buffer};
- node_builder.set_user("testuser");
- node_builder.set_removed(true);
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("testuser");
+ node_builder.object().set_removed(true);
}
buffer.commit();
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1);
@@ -64,19 +68,21 @@ TEST_CASE("Purge data from buffer") {
}
SECTION("purge buffer with two objects, first gets deleted") {
+ osmium::memory::Buffer buffer(buffer_size);
+
{
- osmium::builder::NodeBuilder node_builder{buffer};
- node_builder.set_user("testuser");
- node_builder.set_removed(true);
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("testuser");
+ node_builder.object().set_removed(true);
}
buffer.commit();
- const size_t size1 = buffer.committed();
+ size_t size1 = buffer.committed();
{
- osmium::builder::NodeBuilder node_builder{buffer};
- node_builder.set_user("testuser");
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("testuser");
}
buffer.commit();
- const size_t size2 = buffer.committed() - size1;
+ size_t size2 = buffer.committed() - size1;
REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2);
CallbackClass callback;
@@ -88,16 +94,18 @@ TEST_CASE("Purge data from buffer") {
}
SECTION("purge buffer with two objects, second gets deleted") {
+ osmium::memory::Buffer buffer(buffer_size);
+
{
- osmium::builder::NodeBuilder node_builder{buffer};
- node_builder.set_user("testuser_longer_name");
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("testuser_longer_name");
}
buffer.commit();
size_t size1 = buffer.committed();
{
- osmium::builder::NodeBuilder node_builder{buffer};
- node_builder.set_user("testuser");
- node_builder.set_removed(true);
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("testuser");
+ node_builder.object().set_removed(true);
}
buffer.commit();
@@ -112,22 +120,24 @@ TEST_CASE("Purge data from buffer") {
}
SECTION("purge buffer with three objects, middle one gets deleted") {
+ osmium::memory::Buffer buffer(buffer_size);
+
{
- osmium::builder::NodeBuilder node_builder{buffer};
- node_builder.set_user("testuser_longer_name");
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("testuser_longer_name");
}
buffer.commit();
{
- osmium::builder::NodeBuilder node_builder{buffer};
- node_builder.set_user("testuser");
- node_builder.set_removed(true);
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("testuser");
+ node_builder.object().set_removed(true);
}
buffer.commit();
{
- osmium::builder::NodeBuilder node_builder{buffer};
- node_builder.set_user("sn");
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("sn");
}
buffer.commit();
@@ -141,24 +151,26 @@ TEST_CASE("Purge data from buffer") {
}
SECTION("purge buffer with three objects, all get deleted") {
+ osmium::memory::Buffer buffer(buffer_size);
+
{
- osmium::builder::NodeBuilder node_builder{buffer};
- node_builder.set_user("testuser_longer_name");
- node_builder.set_removed(true);
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("testuser_longer_name");
+ node_builder.object().set_removed(true);
}
buffer.commit();
{
- osmium::builder::NodeBuilder node_builder{buffer};
- node_builder.set_user("testuser");
- node_builder.set_removed(true);
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("testuser");
+ node_builder.object().set_removed(true);
}
buffer.commit();
{
- osmium::builder::NodeBuilder node_builder{buffer};
- node_builder.set_user("sn");
- node_builder.set_removed(true);
+ osmium::builder::NodeBuilder node_builder(buffer);
+ node_builder.add_user("sn");
+ node_builder.object().set_removed(true);
}
buffer.commit();
diff --git a/test/t/builder/test_object_builder.cpp b/test/t/builder/test_object_builder.cpp
deleted file mode 100644
index 5b12564..0000000
--- a/test/t/builder/test_object_builder.cpp
+++ /dev/null
@@ -1,444 +0,0 @@
-
-#include "catch.hpp"
-
-#include <osmium/builder/osm_object_builder.hpp>
-#include <osmium/memory/buffer.hpp>
-#include <osmium/osm.hpp>
-
-TEST_CASE("create objects using builder") {
- osmium::memory::Buffer buffer{1024*10};
- std::string user;
-
- SECTION("complete node with tags") {
- SECTION("user length 0") {
- user = "";
- }
- SECTION("user length 1") {
- user = "1";
- }
- SECTION("user length 2") {
- user = "12";
- }
- SECTION("user length 3") {
- user = "123";
- }
- SECTION("user length 4") {
- user = "1234";
- }
- SECTION("user length 5") {
- user = "12345";
- }
- SECTION("user length 6") {
- user = "123456";
- }
- SECTION("user length 7") {
- user = "1234567";
- }
- SECTION("user length 8") {
- user = "12345678";
- }
- SECTION("user length 9") {
- user = "123456789";
- }
- SECTION("user length 10") {
- user = "1234567890";
- }
- SECTION("user length 11") {
- user = "12345678901";
- }
- SECTION("user length 12") {
- user = "123456789012";
- }
- SECTION("user length 13") {
- user = "1234567890123";
- }
- SECTION("user length 14") {
- user = "12345678901234";
- }
- SECTION("user length 15") {
- user = "123456789012345";
- }
- SECTION("user length 16") {
- user = "1234567890123456";
- }
- SECTION("user length 17") {
- user = "12345678901234567";
- }
- SECTION("user length 18") {
- user = "123456789012345678";
- }
-
- osmium::Location loc{1.2, 3.4};
-
- {
- osmium::builder::NodeBuilder builder{buffer};
-
- builder.set_id(17)
- .set_visible(true)
- .set_version(1)
- .set_changeset(123)
- .set_uid(555)
- .set_timestamp("2015-07-01T00:00:01Z")
- .set_location(loc)
- .set_user(user);
-
- builder.add_tags({{"highway", "primary"}, {"oneway", "yes"}});
- }
-
- const auto& node = buffer.get<osmium::Node>(buffer.commit());
-
- REQUIRE(node.id() == 17);
- REQUIRE(node.version() == 1);
- REQUIRE(node.changeset() == 123);
- REQUIRE(node.uid() == 555);
- REQUIRE(node.timestamp() == osmium::Timestamp{"2015-07-01T00:00:01Z"});
- REQUIRE(node.location() == loc);
-
- REQUIRE(user == node.user());
-
- REQUIRE(node.tags().size() == 2);
- }
-
- SECTION("complete way with tags") {
- SECTION("user length 0") {
- user = "";
- }
- SECTION("user length 1") {
- user = "1";
- }
- SECTION("user length 2") {
- user = "12";
- }
- SECTION("user length 3") {
- user = "123";
- }
- SECTION("user length 4") {
- user = "1234";
- }
- SECTION("user length 5") {
- user = "12345";
- }
- SECTION("user length 6") {
- user = "123456";
- }
- SECTION("user length 7") {
- user = "1234567";
- }
- SECTION("user length 8") {
- user = "12345678";
- }
- SECTION("user length 9") {
- user = "123456789";
- }
- SECTION("user length 10") {
- user = "1234567890";
- }
- SECTION("user length 11") {
- user = "12345678901";
- }
- SECTION("user length 12") {
- user = "123456789012";
- }
- SECTION("user length 13") {
- user = "1234567890123";
- }
- SECTION("user length 14") {
- user = "12345678901234";
- }
- SECTION("user length 15") {
- user = "123456789012345";
- }
- SECTION("user length 16") {
- user = "1234567890123456";
- }
- SECTION("user length 17") {
- user = "12345678901234567";
- }
- SECTION("user length 18") {
- user = "123456789012345678";
- }
-
- {
- osmium::builder::WayBuilder builder{buffer};
-
- builder.set_id(17)
- .set_visible(true)
- .set_version(1)
- .set_changeset(123)
- .set_uid(555)
- .set_timestamp("2015-07-01T00:00:01Z")
- .set_user(user);
-
- builder.add_tags({{"highway", "primary"}, {"oneway", "yes"}});
- }
-
- const auto& way = buffer.get<osmium::Way>(buffer.commit());
-
- REQUIRE(way.id() == 17);
- REQUIRE(way.version() == 1);
- REQUIRE(way.changeset() == 123);
- REQUIRE(way.uid() == 555);
- REQUIRE(way.timestamp() == osmium::Timestamp{"2015-07-01T00:00:01Z"});
-
- REQUIRE(user == way.user());
-
- REQUIRE(way.tags().size() == 2);
- }
-
- SECTION("complete relation with tags") {
- SECTION("user length 0") {
- user = "";
- }
- SECTION("user length 1") {
- user = "1";
- }
- SECTION("user length 2") {
- user = "12";
- }
- SECTION("user length 3") {
- user = "123";
- }
- SECTION("user length 4") {
- user = "1234";
- }
- SECTION("user length 5") {
- user = "12345";
- }
- SECTION("user length 6") {
- user = "123456";
- }
- SECTION("user length 7") {
- user = "1234567";
- }
- SECTION("user length 8") {
- user = "12345678";
- }
- SECTION("user length 9") {
- user = "123456789";
- }
- SECTION("user length 10") {
- user = "1234567890";
- }
- SECTION("user length 11") {
- user = "12345678901";
- }
- SECTION("user length 12") {
- user = "123456789012";
- }
- SECTION("user length 13") {
- user = "1234567890123";
- }
- SECTION("user length 14") {
- user = "12345678901234";
- }
- SECTION("user length 15") {
- user = "123456789012345";
- }
- SECTION("user length 16") {
- user = "1234567890123456";
- }
- SECTION("user length 17") {
- user = "12345678901234567";
- }
- SECTION("user length 18") {
- user = "123456789012345678";
- }
-
- {
- osmium::builder::RelationBuilder builder{buffer};
-
- builder.set_id(17)
- .set_visible(true)
- .set_version(1)
- .set_changeset(123)
- .set_uid(555)
- .set_timestamp("2015-07-01T00:00:01Z")
- .set_user(user);
-
- builder.add_tags({{"highway", "primary"}, {"oneway", "yes"}});
- }
-
- const auto& relation = buffer.get<osmium::Relation>(buffer.commit());
-
- REQUIRE(relation.id() == 17);
- REQUIRE(relation.version() == 1);
- REQUIRE(relation.changeset() == 123);
- REQUIRE(relation.uid() == 555);
- REQUIRE(relation.timestamp() == osmium::Timestamp{"2015-07-01T00:00:01Z"});
-
- REQUIRE(user == relation.user());
-
- REQUIRE(relation.tags().size() == 2);
- }
-
- SECTION("complete changeset with tags") {
- osmium::Location bl{-1.2, -3.4};
- osmium::Location tr{1.2, 3.4};
-
- SECTION("user length 0") {
- user = "";
- }
- SECTION("user length 1") {
- user = "1";
- }
- SECTION("user length 2") {
- user = "12";
- }
- SECTION("user length 3") {
- user = "123";
- }
- SECTION("user length 4") {
- user = "1234";
- }
- SECTION("user length 5") {
- user = "12345";
- }
- SECTION("user length 6") {
- user = "123456";
- }
- SECTION("user length 7") {
- user = "1234567";
- }
- SECTION("user length 8") {
- user = "12345678";
- }
- SECTION("user length 9") {
- user = "123456789";
- }
- SECTION("user length 10") {
- user = "1234567890";
- }
- SECTION("user length 11") {
- user = "12345678901";
- }
- SECTION("user length 12") {
- user = "123456789012";
- }
- SECTION("user length 13") {
- user = "1234567890123";
- }
- SECTION("user length 14") {
- user = "12345678901234";
- }
- SECTION("user length 15") {
- user = "123456789012345";
- }
- SECTION("user length 16") {
- user = "1234567890123456";
- }
- SECTION("user length 17") {
- user = "12345678901234567";
- }
- SECTION("user length 18") {
- user = "123456789012345678";
- }
-
- {
- osmium::builder::ChangesetBuilder builder{buffer};
-
- builder.set_id(17)
- .set_uid(222)
- .set_created_at(osmium::Timestamp{"2016-07-03T01:23:45Z"})
- .set_closed_at(osmium::Timestamp{"2016-07-03T01:23:48Z"})
- .set_num_changes(3)
- .set_num_comments(2)
- .set_bounds(osmium::Box{bl, tr})
- .set_user(user);
- }
-
- const auto& changeset = buffer.get<osmium::Changeset>(buffer.commit());
-
- REQUIRE(changeset.id() == 17);
- REQUIRE(changeset.uid() == 222);
- REQUIRE(changeset.created_at() == osmium::Timestamp{"2016-07-03T01:23:45Z"});
- REQUIRE(changeset.closed_at() == osmium::Timestamp{"2016-07-03T01:23:48Z"});
- REQUIRE(changeset.num_changes() == 3);
- REQUIRE(changeset.num_comments() == 2);
-
- const auto& box = changeset.bounds();
- REQUIRE(box.bottom_left() == bl);
- REQUIRE(box.top_right() == tr);
-
- REQUIRE(user == changeset.user());
- }
-
-}
-
-TEST_CASE("no call to set_user on node") {
- osmium::memory::Buffer buffer{1024*10};
-
- {
- osmium::builder::NodeBuilder builder{buffer};
- }
-
- const auto& node = buffer.get<osmium::Node>(buffer.commit());
-
- REQUIRE(*node.user() == '\0');
-}
-
-TEST_CASE("set_user with length on node") {
- osmium::memory::Buffer buffer{1024*10};
- std::string user = "userx";
-
- {
- osmium::builder::NodeBuilder builder{buffer};
- builder.set_user(user.c_str(), 4);
- }
-
- const auto& node = buffer.get<osmium::Node>(buffer.commit());
-
- REQUIRE(std::string{"user"} == node.user());
-}
-
-TEST_CASE("no call to set_user on way") {
- osmium::memory::Buffer buffer{1024*10};
-
- {
- osmium::builder::WayBuilder builder{buffer};
- }
-
- const auto& way = buffer.get<osmium::Way>(buffer.commit());
-
- REQUIRE(*way.user() == '\0');
-}
-
-TEST_CASE("set_user with length on way") {
- osmium::memory::Buffer buffer{1024*10};
- std::string user = "userx";
-
- {
- osmium::builder::WayBuilder builder{buffer};
- builder.set_user(user.c_str(), 4);
- }
-
- const auto& way = buffer.get<osmium::Way>(buffer.commit());
-
- REQUIRE(std::string{"user"} == way.user());
-}
-
-TEST_CASE("no call to set_user on changeset") {
- osmium::memory::Buffer buffer{1024*10};
-
- {
- osmium::builder::ChangesetBuilder builder{buffer};
- }
-
- const auto& changeset = buffer.get<osmium::Changeset>(buffer.commit());
-
- REQUIRE(*changeset.user() == '\0');
-}
-
-TEST_CASE("set_user with length on changeset") {
- osmium::memory::Buffer buffer{1024*10};
- std::string user = "userx";
-
- {
- osmium::builder::ChangesetBuilder builder{buffer};
- builder.set_user(user.c_str(), 4);
- }
-
- const auto& changeset = buffer.get<osmium::Changeset>(buffer.commit());
-
- REQUIRE(std::string{"user"} == changeset.user());
-}
-
diff --git a/test/t/geom/helper.hpp b/test/t/geom/helper.hpp
new file mode 100644
index 0000000..e0cefe6
--- /dev/null
+++ b/test/t/geom/helper.hpp
@@ -0,0 +1,15 @@
+#ifndef TEST_GEOM_HELPER_HPP
+#define TEST_GEOM_HELPER_HPP
+
+#include <string>
+
+#include <geos/io/WKBWriter.h>
+
+inline std::string geos_to_wkb(const geos::geom::Geometry* geometry) {
+ std::stringstream ss;
+ geos::io::WKBWriter wkb_writer;
+ wkb_writer.writeHEX(*geometry, ss);
+ return ss.str();
+}
+
+#endif // TEST_GEOM_HELPER_HPP
diff --git a/test/t/geom/test_crs.cpp b/test/t/geom/test_crs.cpp
index d8f7c36..c8fbc09 100644
--- a/test/t/geom/test_crs.cpp
+++ b/test/t/geom/test_crs.cpp
@@ -5,12 +5,12 @@
#include <osmium/geom/projection.hpp>
TEST_CASE("CRS") {
- const osmium::geom::CRS wgs84{4326};
- const osmium::geom::CRS mercator{3857};
+ osmium::geom::CRS wgs84{4326};
+ osmium::geom::CRS mercator{3857};
- const osmium::geom::Coordinates c{osmium::geom::deg_to_rad(1.2), osmium::geom::deg_to_rad(3.4)};
- const auto ct = osmium::geom::transform(wgs84, mercator, c);
- const auto c2 = osmium::geom::transform(mercator, wgs84, ct);
+ osmium::geom::Coordinates c{osmium::geom::deg_to_rad(1.2), osmium::geom::deg_to_rad(3.4)};
+ auto ct = osmium::geom::transform(wgs84, mercator, c);
+ auto c2 = osmium::geom::transform(mercator, wgs84, ct);
REQUIRE(c.x == Approx(c2.x));
REQUIRE(c.y == Approx(c2.y));
diff --git a/test/t/geom/test_exception.cpp b/test/t/geom/test_exception.cpp
index 4122d17..fe95043 100644
--- a/test/t/geom/test_exception.cpp
+++ b/test/t/geom/test_exception.cpp
@@ -6,9 +6,11 @@
TEST_CASE("Geometry exception") {
- osmium::geometry_error e{"some error message", "node", 17};
- REQUIRE(e.id() == 17);
- REQUIRE(std::string{e.what()} == "some error message (node_id=17)");
+ 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 08efc03..42fc864 100644
--- a/test/t/geom/test_factory_with_projection.cpp
+++ b/test/t/geom/test_factory_with_projection.cpp
@@ -1,21 +1,41 @@
#include "catch.hpp"
+#include <osmium/geom/geos.hpp>
#include <osmium/geom/mercator_projection.hpp>
#include <osmium/geom/projection.hpp>
#include <osmium/geom/wkb.hpp>
#include <osmium/geom/wkt.hpp>
-TEST_CASE("Projection using MercatorProjection class to WKT") {
- osmium::geom::WKTFactory<osmium::geom::MercatorProjection> factory{2};
+#include "helper.hpp"
- const std::string wkt{factory.create_point(osmium::Location{3.2, 4.2})};
- REQUIRE(wkt == "POINT(356222.37 467961.14)");
-}
+TEST_CASE("Projection") {
-TEST_CASE("Projection using Projection class to WKT") {
- osmium::geom::WKTFactory<osmium::geom::Projection> factory{osmium::geom::Projection{3857}, 2};
+ SECTION("point_mercator") {
+ osmium::geom::WKTFactory<osmium::geom::MercatorProjection> factory(2);
- const std::string wkt{factory.create_point(osmium::Location{3.2, 4.2})};
- REQUIRE(wkt == "POINT(356222.37 467961.14)");
-}
+ 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);
+
+ 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));
+
+ 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();
+ }
+
+}
diff --git a/test/t/geom/test_geojson.cpp b/test/t/geom/test_geojson.cpp
index 5724936..725be7f 100644
--- a/test/t/geom/test_geojson.cpp
+++ b/test/t/geom/test_geojson.cpp
@@ -5,143 +5,162 @@
#include "area_helper.hpp"
#include "wnl_helper.hpp"
-TEST_CASE("GeoJSON point geometry") {
+TEST_CASE("GeoJSON_Geometry") {
+
+SECTION("point") {
osmium::geom::GeoJSONFactory<> factory;
- SECTION("point") {
- const std::string json{factory.create_point(osmium::Location{3.2, 4.2})};
- REQUIRE(std::string{"{\"type\":\"Point\",\"coordinates\":[3.2,4.2]}"} == json);
- }
+ std::string json {factory.create_point(osmium::Location(3.2, 4.2))};
+ REQUIRE(std::string{"{\"type\":\"Point\",\"coordinates\":[3.2,4.2]}"} == json);
+}
- SECTION("empty_point") {
- REQUIRE_THROWS_AS(factory.create_point(osmium::Location{}), osmium::invalid_location);
- }
+SECTION("empty_point") {
+ osmium::geom::GeoJSONFactory<> factory;
+ REQUIRE_THROWS_AS(factory.create_point(osmium::Location()), osmium::invalid_location);
}
-TEST_CASE("GeoJSON linestring geometry") {
+SECTION("linestring") {
osmium::geom::GeoJSONFactory<> factory;
- osmium::memory::Buffer buffer{1000};
- SECTION("linestring, default") {
- const auto& wnl = create_test_wnl_okay(buffer);
- const std::string json{factory.create_linestring(wnl)};
+ osmium::memory::Buffer buffer(1000);
+ auto &wnl = create_test_wnl_okay(buffer);
+
+ {
+ std::string json {factory.create_linestring(wnl)};
REQUIRE(std::string{"{\"type\":\"LineString\",\"coordinates\":[[3.2,4.2],[3.5,4.7],[3.6,4.9]]}"} == json);
}
- SECTION("linestring, unique, backwards") {
- const auto& wnl = create_test_wnl_okay(buffer);
- const std::string json{factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward)};
+ {
+ std::string json {factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward)};
REQUIRE(std::string{"{\"type\":\"LineString\",\"coordinates\":[[3.6,4.9],[3.5,4.7],[3.2,4.2]]}"} == json);
}
- SECTION("linestring, all") {
- const auto& wnl = create_test_wnl_okay(buffer);
- const std::string json{factory.create_linestring(wnl, osmium::geom::use_nodes::all)};
+ {
+ std::string json {factory.create_linestring(wnl, osmium::geom::use_nodes::all)};
REQUIRE(std::string{"{\"type\":\"LineString\",\"coordinates\":[[3.2,4.2],[3.5,4.7],[3.5,4.7],[3.6,4.9]]}"} == json);
}
- SECTION("linestring, all, backwards") {
- const auto& wnl = create_test_wnl_okay(buffer);
- const std::string json{factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)};
+ {
+ std::string json {factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)};
REQUIRE(std::string{"{\"type\":\"LineString\",\"coordinates\":[[3.6,4.9],[3.5,4.7],[3.5,4.7],[3.2,4.2]]}"} == json);
}
+}
- SECTION("empty_linestring") {
- const auto& wnl = create_test_wnl_empty(buffer);
+SECTION("empty_linestring") {
+ osmium::geom::GeoJSONFactory<> factory;
- REQUIRE_THROWS_AS(factory.create_linestring(wnl), osmium::geometry_error);
- REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward), osmium::geometry_error);
- REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::all), osmium::geometry_error);
- REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward), osmium::geometry_error);
- }
+ osmium::memory::Buffer buffer(1000);
+ auto& wnl = create_test_wnl_empty(buffer);
- SECTION("linestring with two same locations") {
- const auto& wnl = create_test_wnl_same_location(buffer);
+ REQUIRE_THROWS_AS(factory.create_linestring(wnl), osmium::geometry_error);
+ REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward), osmium::geometry_error);
+ REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::all), osmium::geometry_error);
+ REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward), osmium::geometry_error);
+}
- REQUIRE_THROWS_AS(factory.create_linestring(wnl), osmium::geometry_error);
- REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward), osmium::geometry_error);
+SECTION("linestring_with_two_same_locations") {
+ osmium::geom::GeoJSONFactory<> factory;
- {
- const std::string json{factory.create_linestring(wnl, osmium::geom::use_nodes::all)};
- REQUIRE(std::string{"{\"type\":\"LineString\",\"coordinates\":[[3.5,4.7],[3.5,4.7]]}"} == json);
- }
+ osmium::memory::Buffer buffer(1000);
+ auto& wnl = create_test_wnl_same_location(buffer);
- {
- const std::string json{factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)};
- REQUIRE(std::string{"{\"type\":\"LineString\",\"coordinates\":[[3.5,4.7],[3.5,4.7]]}"} == json);
- }
+ REQUIRE_THROWS_AS(factory.create_linestring(wnl), osmium::geometry_error);
+ REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward), osmium::geometry_error);
+
+ {
+ std::string json {factory.create_linestring(wnl, osmium::geom::use_nodes::all)};
+ REQUIRE(std::string{"{\"type\":\"LineString\",\"coordinates\":[[3.5,4.7],[3.5,4.7]]}"} == json);
}
- SECTION("linestring with undefined location") {
- const auto& wnl = create_test_wnl_undefined_location(buffer);
- REQUIRE_THROWS_AS(factory.create_linestring(wnl), osmium::invalid_location);
+ {
+ std::string json {factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)};
+ REQUIRE(std::string{"{\"type\":\"LineString\",\"coordinates\":[[3.5,4.7],[3.5,4.7]]}"} == json);
}
+}
+
+SECTION("linestring_with_undefined_location") {
+ osmium::geom::GeoJSONFactory<> factory;
+
+ osmium::memory::Buffer buffer(1000);
+ auto& wnl = create_test_wnl_undefined_location(buffer);
+ REQUIRE_THROWS_AS(factory.create_linestring(wnl), osmium::invalid_location);
}
-TEST_CASE("GeoJSON area geometry") {
+SECTION("area_1outer_0inner") {
osmium::geom::GeoJSONFactory<> factory;
- osmium::memory::Buffer buffer{1000};
- SECTION("area_1outer_0inner") {
- const osmium::Area& area = create_test_area_1outer_0inner(buffer);
+ osmium::memory::Buffer buffer(1000);
+ const osmium::Area& area = create_test_area_1outer_0inner(buffer);
- REQUIRE(!area.is_multipolygon());
- REQUIRE(std::distance(area.cbegin(), area.cend()) == 2);
- REQUIRE(area.subitems<osmium::OuterRing>().size() == area.num_rings().first);
+ REQUIRE(!area.is_multipolygon());
+ REQUIRE(std::distance(area.cbegin(), area.cend()) == 2);
+ REQUIRE(area.subitems<osmium::OuterRing>().size() == area.num_rings().first);
- std::string json{factory.create_multipolygon(area)};
+ {
+ std::string json {factory.create_multipolygon(area)};
REQUIRE(std::string{"{\"type\":\"MultiPolygon\",\"coordinates\":[[[[3.2,4.2],[3.5,4.7],[3.6,4.9],[3.2,4.2]]]]}"} == json);
}
+}
+
+SECTION("area_1outer_1inner") {
+ osmium::geom::GeoJSONFactory<> factory;
- SECTION("area_1outer_1inner") {
- const osmium::Area& area = create_test_area_1outer_1inner(buffer);
+ osmium::memory::Buffer buffer(1000);
+ const osmium::Area& area = create_test_area_1outer_1inner(buffer);
- REQUIRE(!area.is_multipolygon());
- REQUIRE(std::distance(area.cbegin(), area.cend()) == 3);
- REQUIRE(area.subitems<osmium::OuterRing>().size() == area.num_rings().first);
- REQUIRE(area.subitems<osmium::InnerRing>().size() == area.num_rings().second);
+ REQUIRE(!area.is_multipolygon());
+ REQUIRE(std::distance(area.cbegin(), area.cend()) == 3);
+ REQUIRE(area.subitems<osmium::OuterRing>().size() == area.num_rings().first);
+ REQUIRE(area.subitems<osmium::InnerRing>().size() == area.num_rings().second);
- std::string json{factory.create_multipolygon(area)};
+ {
+ std::string json {factory.create_multipolygon(area)};
REQUIRE(std::string{"{\"type\":\"MultiPolygon\",\"coordinates\":[[[[0.1,0.1],[9.1,0.1],[9.1,9.1],[0.1,9.1],[0.1,0.1]],[[1,1],[8,1],[8,8],[1,8],[1,1]]]]}"} == json);
}
+}
+
+SECTION("area_2outer_2inner") {
+ osmium::geom::GeoJSONFactory<> factory;
- SECTION("area_2outer_2inner") {
- const osmium::Area& area = create_test_area_2outer_2inner(buffer);
-
- REQUIRE(area.is_multipolygon());
- REQUIRE(std::distance(area.cbegin(), area.cend()) == 5);
- REQUIRE(area.subitems<osmium::OuterRing>().size() == area.num_rings().first);
- REQUIRE(area.subitems<osmium::InnerRing>().size() == area.num_rings().second);
-
- int outer_ring=0;
- int inner_ring=0;
- for (const auto& outer : area.outer_rings()) {
- if (outer_ring == 0) {
- REQUIRE(outer.front().ref() == 1);
- } else if (outer_ring == 1) {
- REQUIRE(outer.front().ref() == 100);
+ osmium::memory::Buffer buffer(1000);
+ const osmium::Area& area = create_test_area_2outer_2inner(buffer);
+
+ REQUIRE(area.is_multipolygon());
+ REQUIRE(std::distance(area.cbegin(), area.cend()) == 5);
+ REQUIRE(area.subitems<osmium::OuterRing>().size() == area.num_rings().first);
+ REQUIRE(area.subitems<osmium::InnerRing>().size() == area.num_rings().second);
+
+ int outer_ring=0;
+ int inner_ring=0;
+ for (const auto& outer : area.outer_rings()) {
+ if (outer_ring == 0) {
+ REQUIRE(outer.front().ref() == 1);
+ } else if (outer_ring == 1) {
+ REQUIRE(outer.front().ref() == 100);
+ } else {
+ REQUIRE(false);
+ }
+ for (const auto& inner : area.inner_rings(outer)) {
+ if (outer_ring == 0 && inner_ring == 0) {
+ REQUIRE(inner.front().ref() == 5);
+ } else if (outer_ring == 0 && inner_ring == 1) {
+ REQUIRE(inner.front().ref() == 10);
} else {
REQUIRE(false);
}
- for (const auto& inner : area.inner_rings(outer)) {
- if (outer_ring == 0 && inner_ring == 0) {
- REQUIRE(inner.front().ref() == 5);
- } else if (outer_ring == 0 && inner_ring == 1) {
- REQUIRE(inner.front().ref() == 10);
- } else {
- REQUIRE(false);
- }
- ++inner_ring;
- }
- inner_ring = 0;
- ++outer_ring;
+ ++inner_ring;
}
+ inner_ring = 0;
+ ++outer_ring;
+ }
- std::string json{factory.create_multipolygon(area)};
+ {
+ std::string json {factory.create_multipolygon(area)};
REQUIRE(std::string{"{\"type\":\"MultiPolygon\",\"coordinates\":[[[[0.1,0.1],[9.1,0.1],[9.1,9.1],[0.1,9.1],[0.1,0.1]],[[1,1],[4,1],[4,4],[1,4],[1,1]],[[5,5],[5,7],[7,7],[5,5]]],[[[10,10],[11,10],[11,11],[10,11],[10,10]]]]}"} == json);
}
+}
}
diff --git a/test/t/geom/test_geos.cpp b/test/t/geom/test_geos.cpp
index 8e7fac4..f74027c 100644
--- a/test/t/geom/test_geos.cpp
+++ b/test/t/geom/test_geos.cpp
@@ -1,10 +1,6 @@
-
-#include <osmium/geom/geos.hpp>
-
-#ifdef OSMIUM_WITH_GEOS
-
#include "catch.hpp"
+#include <osmium/geom/geos.hpp>
#include <osmium/geom/mercator_projection.hpp>
#include "area_helper.hpp"
@@ -13,7 +9,7 @@
TEST_CASE("GEOS geometry factory - create point") {
osmium::geom::GEOSFactory<> factory;
- const std::unique_ptr<geos::geom::Point> point{factory.create_point(osmium::Location{3.2, 4.2})};
+ std::unique_ptr<geos::geom::Point> point {factory.create_point(osmium::Location(3.2, 4.2))};
REQUIRE(3.2 == point->getX());
REQUIRE(4.2 == point->getY());
REQUIRE(4326 == point->getSRID());
@@ -22,7 +18,7 @@ TEST_CASE("GEOS geometry factory - create point") {
TEST_CASE("GEOS geometry factory - create point in web mercator") {
osmium::geom::GEOSFactory<osmium::geom::MercatorProjection> factory;
- const std::unique_ptr<geos::geom::Point> point{factory.create_point(osmium::Location{3.2, 4.2})};
+ std::unique_ptr<geos::geom::Point> point {factory.create_point(osmium::Location(3.2, 4.2))};
REQUIRE(Approx(356222.3705384755l) == point->getX());
REQUIRE(Approx(467961.143605213l) == point->getY());
REQUIRE(3857 == point->getSRID());
@@ -30,9 +26,9 @@ TEST_CASE("GEOS geometry factory - create point in web mercator") {
TEST_CASE("GEOS geometry factory - create point with externally created GEOS factory") {
geos::geom::GeometryFactory geos_factory;
- osmium::geom::GEOSFactory<> factory{geos_factory};
+ osmium::geom::GEOSFactory<> factory(geos_factory);
- const std::unique_ptr<geos::geom::Point> point{factory.create_point(osmium::Location{3.2, 4.2})};
+ std::unique_ptr<geos::geom::Point> point {factory.create_point(osmium::Location(3.2, 4.2))};
REQUIRE(3.2 == point->getX());
REQUIRE(4.2 == point->getY());
REQUIRE(0 == point->getSRID());
@@ -41,45 +37,45 @@ TEST_CASE("GEOS geometry factory - create point with externally created GEOS fac
TEST_CASE("GEOS geometry factory - can not create from invalid location") {
osmium::geom::GEOSFactory<> factory;
- REQUIRE_THROWS_AS(factory.create_point(osmium::Location{}), osmium::invalid_location);
+ REQUIRE_THROWS_AS(factory.create_point(osmium::Location()), osmium::invalid_location);
}
TEST_CASE("GEOS geometry factory - create linestring") {
osmium::geom::GEOSFactory<> factory;
- osmium::memory::Buffer buffer{10000};
- const auto& wnl = create_test_wnl_okay(buffer);
+ osmium::memory::Buffer buffer(10000);
+ auto &wnl = create_test_wnl_okay(buffer);
SECTION("from way node list") {
- const std::unique_ptr<geos::geom::LineString> linestring{factory.create_linestring(wnl)};
+ std::unique_ptr<geos::geom::LineString> linestring {factory.create_linestring(wnl)};
REQUIRE(3 == linestring->getNumPoints());
- const auto p0 = std::unique_ptr<geos::geom::Point>(linestring->getPointN(0));
+ std::unique_ptr<geos::geom::Point> p0 = std::unique_ptr<geos::geom::Point>(linestring->getPointN(0));
REQUIRE(3.2 == p0->getX());
- const auto p2 = std::unique_ptr<geos::geom::Point>(linestring->getPointN(2));
+ std::unique_ptr<geos::geom::Point> p2 = std::unique_ptr<geos::geom::Point>(linestring->getPointN(2));
REQUIRE(3.6 == p2->getX());
}
SECTION("without duplicates and backwards") {
- const std::unique_ptr<geos::geom::LineString> linestring{factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward)};
+ std::unique_ptr<geos::geom::LineString> linestring {factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward)};
REQUIRE(3 == linestring->getNumPoints());
- const auto p0 = std::unique_ptr<geos::geom::Point>(linestring->getPointN(0));
+ std::unique_ptr<geos::geom::Point> p0 = std::unique_ptr<geos::geom::Point>(linestring->getPointN(0));
REQUIRE(3.6 == p0->getX());
- const auto p2 = std::unique_ptr<geos::geom::Point>(linestring->getPointN(2));
+ std::unique_ptr<geos::geom::Point> p2 = std::unique_ptr<geos::geom::Point>(linestring->getPointN(2));
REQUIRE(3.2 == p2->getX());
}
SECTION("with duplicates") {
- const std::unique_ptr<geos::geom::LineString> linestring{factory.create_linestring(wnl, osmium::geom::use_nodes::all)};
+ std::unique_ptr<geos::geom::LineString> linestring {factory.create_linestring(wnl, osmium::geom::use_nodes::all)};
REQUIRE(4 == linestring->getNumPoints());
- const auto p0 = std::unique_ptr<geos::geom::Point>(linestring->getPointN(0));
+ std::unique_ptr<geos::geom::Point> p0 = std::unique_ptr<geos::geom::Point>(linestring->getPointN(0));
REQUIRE(3.2 == p0->getX());
}
SECTION("with duplicates and backwards") {
- const std::unique_ptr<geos::geom::LineString> linestring{factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)};
+ std::unique_ptr<geos::geom::LineString> linestring {factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)};
REQUIRE(4 == linestring->getNumPoints());
- const auto p0 = std::unique_ptr<geos::geom::Point>(linestring->getPointN(0));
+ std::unique_ptr<geos::geom::Point> p0 = std::unique_ptr<geos::geom::Point>(linestring->getPointN(0));
REQUIRE(3.6 == p0->getX());
}
}
@@ -87,10 +83,10 @@ TEST_CASE("GEOS geometry factory - create linestring") {
TEST_CASE("GEOS geometry factory - create area with one outer and no inner rings") {
osmium::geom::GEOSFactory<> factory;
- osmium::memory::Buffer buffer{10000};
+ osmium::memory::Buffer buffer(10000);
const osmium::Area& area = create_test_area_1outer_0inner(buffer);
- const std::unique_ptr<geos::geom::MultiPolygon> mp{factory.create_multipolygon(area)};
+ std::unique_ptr<geos::geom::MultiPolygon> mp {factory.create_multipolygon(area)};
REQUIRE(1 == mp->getNumGeometries());
const geos::geom::Polygon* p0 = dynamic_cast<const geos::geom::Polygon*>(mp->getGeometryN(0));
@@ -100,17 +96,17 @@ TEST_CASE("GEOS geometry factory - create area with one outer and no inner rings
const geos::geom::LineString* l0e = p0->getExteriorRing();
REQUIRE(4 == l0e->getNumPoints());
- const auto l0e_p0 = std::unique_ptr<geos::geom::Point>(l0e->getPointN(1));
+ std::unique_ptr<geos::geom::Point> l0e_p0 = std::unique_ptr<geos::geom::Point>(l0e->getPointN(1));
REQUIRE(3.5 == l0e_p0->getX());
}
TEST_CASE("GEOS geometry factory - create area with one outer and one inner ring") {
osmium::geom::GEOSFactory<> factory;
- osmium::memory::Buffer buffer{10000};
+ osmium::memory::Buffer buffer(10000);
const osmium::Area& area = create_test_area_1outer_1inner(buffer);
- const std::unique_ptr<geos::geom::MultiPolygon> mp{factory.create_multipolygon(area)};
+ std::unique_ptr<geos::geom::MultiPolygon> mp {factory.create_multipolygon(area)};
REQUIRE(1 == mp->getNumGeometries());
const geos::geom::Polygon* p0 = dynamic_cast<const geos::geom::Polygon*>(mp->getGeometryN(0));
@@ -127,10 +123,10 @@ TEST_CASE("GEOS geometry factory - create area with one outer and one inner ring
TEST_CASE("GEOS geometry factory - create area with two outer and two inner rings") {
osmium::geom::GEOSFactory<> factory;
- osmium::memory::Buffer buffer{10000};
+ osmium::memory::Buffer buffer(10000);
const osmium::Area& area = create_test_area_2outer_2inner(buffer);
- const std::unique_ptr<geos::geom::MultiPolygon> mp{factory.create_multipolygon(area)};
+ std::unique_ptr<geos::geom::MultiPolygon> mp {factory.create_multipolygon(area)};
REQUIRE(2 == mp->getNumGeometries());
const geos::geom::Polygon* p0 = dynamic_cast<const geos::geom::Polygon*>(mp->getGeometryN(0));
@@ -148,5 +144,3 @@ TEST_CASE("GEOS geometry factory - create area with two outer and two inner ring
REQUIRE(5 == l1e->getNumPoints());
}
-#endif
-
diff --git a/test/t/geom/test_geos_wkb.cpp b/test/t/geom/test_geos_wkb.cpp
new file mode 100644
index 0000000..1fca63b
--- /dev/null
+++ b/test/t/geom/test_geos_wkb.cpp
@@ -0,0 +1,92 @@
+#include "catch.hpp"
+
+#include <osmium/geom/geos.hpp>
+#include <osmium/geom/wkb.hpp>
+
+#include "helper.hpp"
+#include "area_helper.hpp"
+#include "wnl_helper.hpp"
+
+TEST_CASE("WKB_Geometry_with_GEOS") {
+
+SECTION("point") {
+ osmium::geom::WKBFactory<> wkb_factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
+ osmium::geom::GEOSFactory<> geos_factory;
+
+ 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("linestring") {
+ osmium::geom::WKBFactory<> wkb_factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
+ osmium::geom::GEOSFactory<> geos_factory;
+
+ osmium::memory::Buffer buffer(10000);
+ auto &wnl = create_test_wnl_okay(buffer);
+
+ {
+ std::string wkb = wkb_factory.create_linestring(wnl);
+ std::unique_ptr<geos::geom::LineString> geos = geos_factory.create_linestring(wnl);
+ REQUIRE(geos_to_wkb(geos.get()) == wkb);
+ }
+
+ {
+ std::string wkb = wkb_factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward);
+ std::unique_ptr<geos::geom::LineString> geos = geos_factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward);
+ REQUIRE(geos_to_wkb(geos.get()) == wkb);
+ }
+
+ {
+ std::string wkb = wkb_factory.create_linestring(wnl, osmium::geom::use_nodes::all);
+ std::unique_ptr<geos::geom::LineString> geos = geos_factory.create_linestring(wnl, osmium::geom::use_nodes::all);
+ REQUIRE(geos_to_wkb(geos.get()) == wkb);
+ }
+
+ {
+ std::string wkb = wkb_factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward);
+ std::unique_ptr<geos::geom::LineString> geos = geos_factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward);
+ REQUIRE(geos_to_wkb(geos.get()) == wkb);
+ }
+}
+
+SECTION("area_1outer_0inner") {
+ osmium::geom::WKBFactory<> wkb_factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
+ osmium::geom::GEOSFactory<> geos_factory;
+
+ osmium::memory::Buffer buffer(10000);
+ const osmium::Area& area = create_test_area_1outer_0inner(buffer);
+
+ std::string wkb = wkb_factory.create_multipolygon(area);
+ std::unique_ptr<geos::geom::MultiPolygon> geos = geos_factory.create_multipolygon(area);
+ REQUIRE(geos_to_wkb(geos.get()) == wkb);
+}
+
+SECTION("area_1outer_1inner") {
+ osmium::geom::WKBFactory<> wkb_factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
+ osmium::geom::GEOSFactory<> geos_factory;
+
+ osmium::memory::Buffer buffer(10000);
+ const osmium::Area& area = create_test_area_1outer_1inner(buffer);
+
+ std::string wkb = wkb_factory.create_multipolygon(area);
+ std::unique_ptr<geos::geom::MultiPolygon> geos = geos_factory.create_multipolygon(area);
+ REQUIRE(geos_to_wkb(geos.get()) == wkb);
+}
+
+SECTION("area_2outer_2inner") {
+ osmium::geom::WKBFactory<> wkb_factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
+ osmium::geom::GEOSFactory<> geos_factory;
+
+ osmium::memory::Buffer buffer(10000);
+ const osmium::Area& area = create_test_area_2outer_2inner(buffer);
+
+ std::string wkb = wkb_factory.create_multipolygon(area);
+ std::unique_ptr<geos::geom::MultiPolygon> geos = geos_factory.create_multipolygon(area);
+ REQUIRE(geos_to_wkb(geos.get()) == wkb);
+}
+
+}
+
diff --git a/test/t/geom/test_ogr.cpp b/test/t/geom/test_ogr.cpp
index 5e03082..3490c57 100644
--- a/test/t/geom/test_ogr.cpp
+++ b/test/t/geom/test_ogr.cpp
@@ -5,115 +5,121 @@
#include "area_helper.hpp"
#include "wnl_helper.hpp"
-TEST_CASE("OGR point geometry") {
+TEST_CASE("OGR_Geometry") {
+
+SECTION("point") {
osmium::geom::OGRFactory<> factory;
- SECTION("point") {
- std::unique_ptr<OGRPoint> point{factory.create_point(osmium::Location{3.2, 4.2})};
- REQUIRE(3.2 == point->getX());
- REQUIRE(4.2 == point->getY());
- }
+ std::unique_ptr<OGRPoint> point {factory.create_point(osmium::Location(3.2, 4.2))};
+ REQUIRE(3.2 == point->getX());
+ REQUIRE(4.2 == point->getY());
+}
- SECTION("empty_point") {
- REQUIRE_THROWS_AS(factory.create_point(osmium::Location()), osmium::invalid_location);
- }
+SECTION("empty_point") {
+ osmium::geom::OGRFactory<> factory;
+ REQUIRE_THROWS_AS(factory.create_point(osmium::Location()), osmium::invalid_location);
}
-TEST_CASE("OGR linestring geometry") {
+SECTION("linestring") {
osmium::geom::OGRFactory<> factory;
- osmium::memory::Buffer buffer{10000};
- const auto& wnl = create_test_wnl_okay(buffer);
- SECTION("linestring, default") {
- std::unique_ptr<OGRLineString> linestring{factory.create_linestring(wnl)};
+ osmium::memory::Buffer buffer(10000);
+ auto &wnl = create_test_wnl_okay(buffer);
+
+ {
+ std::unique_ptr<OGRLineString> linestring {factory.create_linestring(wnl)};
REQUIRE(3 == linestring->getNumPoints());
REQUIRE(3.2 == linestring->getX(0));
REQUIRE(3.6 == linestring->getX(2));
}
- SECTION("linestring, unique nodes, backwards") {
- std::unique_ptr<OGRLineString> linestring{factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward)};
+ {
+ std::unique_ptr<OGRLineString> linestring {factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward)};
REQUIRE(3 == linestring->getNumPoints());
REQUIRE(3.6 == linestring->getX(0));
REQUIRE(3.2 == linestring->getX(2));
}
- SECTION("linestring, all nodes") {
- std::unique_ptr<OGRLineString> linestring{factory.create_linestring(wnl, osmium::geom::use_nodes::all)};
+ {
+ std::unique_ptr<OGRLineString> linestring {factory.create_linestring(wnl, osmium::geom::use_nodes::all)};
REQUIRE(4 == linestring->getNumPoints());
REQUIRE(3.2 == linestring->getX(0));
}
- SECTION("linestring, all nodes, backwards") {
- std::unique_ptr<OGRLineString> linestring{factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)};
+ {
+ std::unique_ptr<OGRLineString> linestring {factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)};
REQUIRE(4 == linestring->getNumPoints());
REQUIRE(3.6 == linestring->getX(0));
}
-
}
-TEST_CASE("OGR area geometry") {
+SECTION("area_1outer_0inner") {
osmium::geom::OGRFactory<> factory;
- osmium::memory::Buffer buffer{10000};
- SECTION("area_1outer_0inner") {
- const osmium::Area& area = create_test_area_1outer_0inner(buffer);
+ osmium::memory::Buffer buffer(10000);
+ const osmium::Area& area = create_test_area_1outer_0inner(buffer);
- std::unique_ptr<OGRMultiPolygon> mp {factory.create_multipolygon(area)};
- REQUIRE(1 == mp->getNumGeometries());
+ std::unique_ptr<OGRMultiPolygon> mp {factory.create_multipolygon(area)};
+ REQUIRE(1 == mp->getNumGeometries());
- const OGRPolygon* p0 = dynamic_cast<const OGRPolygon*>(mp->getGeometryRef(0));
- REQUIRE(p0);
- REQUIRE(0 == p0->getNumInteriorRings());
+ const OGRPolygon* p0 = dynamic_cast<const OGRPolygon*>(mp->getGeometryRef(0));
+ REQUIRE(p0);
+ REQUIRE(0 == p0->getNumInteriorRings());
- const OGRLineString* l0e = p0->getExteriorRing();
- REQUIRE(4 == l0e->getNumPoints());
+ const OGRLineString* l0e = p0->getExteriorRing();
+ REQUIRE(4 == l0e->getNumPoints());
- REQUIRE(3.5 == l0e->getX(1));
- }
+ REQUIRE(3.5 == l0e->getX(1));
+}
- SECTION("area_1outer_1inner") {
- const osmium::Area& area = create_test_area_1outer_1inner(buffer);
+SECTION("area_1outer_1inner") {
+ osmium::geom::OGRFactory<> factory;
- std::unique_ptr<OGRMultiPolygon> mp {factory.create_multipolygon(area)};
- REQUIRE(1 == mp->getNumGeometries());
+ osmium::memory::Buffer buffer(10000);
+ const osmium::Area& area = create_test_area_1outer_1inner(buffer);
- const OGRPolygon* p0 = dynamic_cast<const OGRPolygon*>(mp->getGeometryRef(0));
- REQUIRE(p0);
- REQUIRE(1 == p0->getNumInteriorRings());
+ std::unique_ptr<OGRMultiPolygon> mp {factory.create_multipolygon(area)};
+ REQUIRE(1 == mp->getNumGeometries());
- const OGRLineString* l0e = p0->getExteriorRing();
- REQUIRE(5 == l0e->getNumPoints());
+ const OGRPolygon* p0 = dynamic_cast<const OGRPolygon*>(mp->getGeometryRef(0));
+ REQUIRE(p0);
+ REQUIRE(1 == p0->getNumInteriorRings());
- const OGRLineString* l0i0 = p0->getInteriorRing(0);
- REQUIRE(5 == l0i0->getNumPoints());
- }
+ const OGRLineString* l0e = p0->getExteriorRing();
+ REQUIRE(5 == l0e->getNumPoints());
+
+ const OGRLineString* l0i0 = p0->getInteriorRing(0);
+ REQUIRE(5 == l0i0->getNumPoints());
+}
- SECTION("area_2outer_2inner") {
- const osmium::Area& area = create_test_area_2outer_2inner(buffer);
+SECTION("area_2outer_2inner") {
+ osmium::geom::OGRFactory<> factory;
- std::unique_ptr<OGRMultiPolygon> mp {factory.create_multipolygon(area)};
- REQUIRE(2 == mp->getNumGeometries());
+ osmium::memory::Buffer buffer(10000);
+ const osmium::Area& area = create_test_area_2outer_2inner(buffer);
- const OGRPolygon* p0 = dynamic_cast<const OGRPolygon*>(mp->getGeometryRef(0));
- REQUIRE(p0);
- REQUIRE(2 == p0->getNumInteriorRings());
+ std::unique_ptr<OGRMultiPolygon> mp {factory.create_multipolygon(area)};
+ REQUIRE(2 == mp->getNumGeometries());
- const OGRLineString* l0e = p0->getExteriorRing();
- REQUIRE(5 == l0e->getNumPoints());
+ const OGRPolygon* p0 = dynamic_cast<const OGRPolygon*>(mp->getGeometryRef(0));
+ REQUIRE(p0);
+ REQUIRE(2 == p0->getNumInteriorRings());
- const OGRPolygon* p1 = dynamic_cast<const OGRPolygon*>(mp->getGeometryRef(1));
- REQUIRE(p1);
- REQUIRE(0 == p1->getNumInteriorRings());
+ const OGRLineString* l0e = p0->getExteriorRing();
+ REQUIRE(5 == l0e->getNumPoints());
- const OGRLineString* l1e = p1->getExteriorRing();
- REQUIRE(5 == l1e->getNumPoints());
- }
+ const OGRPolygon* p1 = dynamic_cast<const OGRPolygon*>(mp->getGeometryRef(1));
+ REQUIRE(p1);
+ REQUIRE(0 == p1->getNumInteriorRings());
+
+ const OGRLineString* l1e = p1->getExteriorRing();
+ REQUIRE(5 == l1e->getNumPoints());
+}
}
diff --git a/test/t/geom/test_ogr_wkb.cpp b/test/t/geom/test_ogr_wkb.cpp
deleted file mode 100644
index 548d143..0000000
--- a/test/t/geom/test_ogr_wkb.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-#include "catch.hpp"
-
-#include <memory>
-#include <sstream>
-#include <string>
-
-#include <osmium/geom/ogr.hpp>
-#include <osmium/geom/wkb.hpp>
-
-#include "area_helper.hpp"
-#include "wnl_helper.hpp"
-
-std::string to_wkb(const OGRGeometry* geometry) {
- std::string buffer;
- buffer.resize(geometry->WkbSize());
-
- geometry->exportToWkb(wkbNDR, const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(buffer.data())));
-
- return buffer;
-}
-
-TEST_CASE("compare WKB point against GDAL/OGR") {
- osmium::geom::WKBFactory<> wkb_factory{osmium::geom::wkb_type::wkb};
- osmium::geom::OGRFactory<> ogr_factory;
-
- osmium::Location loc{3.2, 4.2};
- const std::string wkb{wkb_factory.create_point(loc)};
- const std::unique_ptr<OGRPoint> geometry = ogr_factory.create_point(loc);
- REQUIRE(to_wkb(geometry.get()) == wkb);
-}
-
-TEST_CASE("compare WKB linestring against GDAL/OGR") {
- osmium::geom::WKBFactory<> wkb_factory{osmium::geom::wkb_type::wkb};
- osmium::geom::OGRFactory<> ogr_factory;
- osmium::memory::Buffer buffer{10000};
-
- const auto& wnl = create_test_wnl_okay(buffer);
-
- SECTION("linestring") {
- const std::string wkb{wkb_factory.create_linestring(wnl)};
- const std::unique_ptr<OGRLineString> geometry = ogr_factory.create_linestring(wnl);
- REQUIRE(to_wkb(geometry.get()) == wkb);
- }
-
- SECTION("linestring, unique nodes, backwards") {
- const std::string wkb{wkb_factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward)};
- const std::unique_ptr<OGRLineString> geometry = ogr_factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward);
- REQUIRE(to_wkb(geometry.get()) == wkb);
- }
-
- SECTION("linestring, all nodes, forwards") {
- const std::string wkb{wkb_factory.create_linestring(wnl, osmium::geom::use_nodes::all)};
- const std::unique_ptr<OGRLineString> geometry = ogr_factory.create_linestring(wnl, osmium::geom::use_nodes::all);
- REQUIRE(to_wkb(geometry.get()) == wkb);
- }
-
- SECTION("linestring, all nodes, backwards") {
- const std::string wkb{wkb_factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)};
- const std::unique_ptr<OGRLineString> geometry = ogr_factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward);
- REQUIRE(to_wkb(geometry.get()) == wkb);
- }
-
-}
-
-TEST_CASE("compare WKB area against GDAL/OGR") {
- osmium::geom::WKBFactory<> wkb_factory{osmium::geom::wkb_type::wkb};
- osmium::geom::OGRFactory<> ogr_factory;
- osmium::memory::Buffer buffer{10000};
-
- SECTION("area_1outer_0inner") {
- const osmium::Area& area = create_test_area_1outer_0inner(buffer);
-
- const std::string wkb{wkb_factory.create_multipolygon(area)};
- const std::unique_ptr<OGRMultiPolygon> geometry = ogr_factory.create_multipolygon(area);
- REQUIRE(to_wkb(geometry.get()) == wkb);
- }
-
- SECTION("area_1outer_1inner") {
- const osmium::Area& area = create_test_area_1outer_1inner(buffer);
-
- const std::string wkb{wkb_factory.create_multipolygon(area)};
- const std::unique_ptr<OGRMultiPolygon> geometry = ogr_factory.create_multipolygon(area);
- REQUIRE(to_wkb(geometry.get()) == wkb);
- }
-
- SECTION("area_2outer_2inner") {
- const osmium::Area& area = create_test_area_2outer_2inner(buffer);
-
- const std::string wkb{wkb_factory.create_multipolygon(area)};
- const std::unique_ptr<OGRMultiPolygon> geometry = ogr_factory.create_multipolygon(area);
- REQUIRE(to_wkb(geometry.get()) == wkb);
- }
-
-}
-
-#endif
-
diff --git a/test/t/geom/test_projection.cpp b/test/t/geom/test_projection.cpp
index 14df3bf..5885410 100644
--- a/test/t/geom/test_projection.cpp
+++ b/test/t/geom/test_projection.cpp
@@ -6,121 +6,144 @@
#include <osmium/geom/mercator_projection.hpp>
#include <osmium/geom/projection.hpp>
-TEST_CASE("Indentity Projection") {
+TEST_CASE("Projection") {
+
+SECTION("identity_projection") {
osmium::geom::IdentityProjection projection;
REQUIRE(4326 == projection.epsg());
REQUIRE("+proj=longlat +datum=WGS84 +no_defs" == projection.proj_string());
}
-TEST_CASE("Projection 4326") {
- osmium::geom::Projection projection{4326};
+SECTION("project_location_4326") {
+ osmium::geom::Projection projection(4326);
REQUIRE(4326 == projection.epsg());
REQUIRE("+init=epsg:4326" == projection.proj_string());
- const osmium::Location loc{1.0, 2.0};
- const osmium::geom::Coordinates c{1.0, 2.0};
+ const osmium::Location loc(1.0, 2.0);
+ const osmium::geom::Coordinates c {1.0, 2.0};
REQUIRE(c == projection(loc));
}
-TEST_CASE("Projection 4326 from init string") {
- osmium::geom::Projection projection{"+init=epsg:4326"};
+SECTION("project_location_4326_string") {
+ osmium::geom::Projection projection("+init=epsg:4326");
REQUIRE(-1 == projection.epsg());
REQUIRE("+init=epsg:4326" == projection.proj_string());
- const osmium::Location loc{1.0, 2.0};
- const osmium::geom::Coordinates c{1.0, 2.0};
+ const osmium::Location loc(1.0, 2.0);
+ const osmium::geom::Coordinates c {1.0, 2.0};
REQUIRE(c == projection(loc));
}
-TEST_CASE("Creating projection from unknown init string") {
- REQUIRE_THROWS_AS(osmium::geom::Projection projection{"abc"}, osmium::projection_error);
+SECTION("unknown_projection_string") {
+ REQUIRE_THROWS_AS(osmium::geom::Projection projection("abc"), osmium::projection_error);
}
-TEST_CASE("Creating projection from unknown EPSG code") {
- REQUIRE_THROWS_AS(osmium::geom::Projection projection{9999999}, osmium::projection_error);
+SECTION("unknown_epsg_code") {
+ REQUIRE_THROWS_AS(osmium::geom::Projection projection(9999999), osmium::projection_error);
}
-TEST_CASE("Projection 3857") {
- osmium::geom::Projection projection{3857};
+SECTION("project_location_3857") {
+ osmium::geom::Projection projection(3857);
REQUIRE(3857 == projection.epsg());
REQUIRE("+init=epsg:3857" == projection.proj_string());
- SECTION("Zero coordinates") {
- const osmium::Location loc{0.0, 0.0};
- const osmium::geom::Coordinates c{0.0, 0.0};
+ {
+ const osmium::Location loc(0.0, 0.0);
+ const osmium::geom::Coordinates c {0.0, 0.0};
REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.1));
REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.1));
}
-
- SECTION("Max longitude") {
- const osmium::Location loc{180.0, 0.0};
- const osmium::geom::Coordinates c{20037508.34, 0.0};
+ {
+ const osmium::Location loc(180.0, 0.0);
+ const osmium::geom::Coordinates c {20037508.34, 0.0};
REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.1));
REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.1));
}
-
- SECTION("Min longitude") {
- const osmium::Location loc{-180.0, 0.0};
- const osmium::geom::Coordinates c{-20037508.34, 0.0};
+ {
+ const osmium::Location loc(180.0, 0.0);
+ const osmium::geom::Coordinates c {20037508.34, 0.0};
REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.1));
REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.1));
}
-
- SECTION("Max latitude") {
- const osmium::Location loc{0.0, 85.0511288};
- const osmium::geom::Coordinates c{0.0, 20037508.34};
+ {
+ const osmium::Location loc(0.0, 85.0511288);
+ const osmium::geom::Coordinates c {0.0, 20037508.34};
REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.1));
REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.1));
}
}
-TEST_CASE("MercatorProjection") {
+SECTION("project_location_mercator") {
osmium::geom::MercatorProjection projection;
- SECTION("Zero coordinates") {
- const osmium::Location loc{0.0, 0.0};
- const osmium::geom::Coordinates c{0.0, 0.0};
+ {
+ const osmium::Location loc(0.0, 0.0);
+ const osmium::geom::Coordinates c {0.0, 0.0};
REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.1));
REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.1));
}
-
- SECTION("Max longitude") {
- const osmium::Location loc{180.0, 0.0};
- const osmium::geom::Coordinates c{20037508.34, 0.0};
+ {
+ const osmium::Location loc(180.0, 0.0);
+ const osmium::geom::Coordinates c {20037508.34, 0.0};
REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.1));
REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.1));
}
-
- SECTION("Min longitude") {
- const osmium::Location loc{-180.0, 0.0};
- const osmium::geom::Coordinates c{-20037508.34, 0.0};
+ {
+ const osmium::Location loc(180.0, 0.0);
+ const osmium::geom::Coordinates c {20037508.34, 0.0};
REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.1));
REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.1));
}
-
- SECTION("Max latitude") {
- const osmium::Location loc{0.0, 85.0511288};
- const osmium::geom::Coordinates c{0.0, 20037508.34};
+ {
+ const osmium::Location loc(0.0, 85.0511288);
+ const osmium::geom::Coordinates c {0.0, 20037508.34};
REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.1));
REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.1));
}
}
-TEST_CASE("Compare mercator implementations") {
+SECTION("compare_mercators") {
osmium::geom::MercatorProjection projection_merc;
- osmium::geom::Projection projection_3857{3857};
-
- SECTION("random coordinates") {
- 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 < 10000; ++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));
- }
+ osmium::geom::Projection projection_3857(3857);
+ REQUIRE(3857 == projection_3857.epsg());
+ REQUIRE("+init=epsg:3857" == projection_3857.proj_string());
+
+ {
+ const osmium::Location loc(4.2, 27.3);
+ 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));
+ }
+ {
+ const osmium::Location loc(160.789, -42.42);
+ 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));
+ }
+ {
+ const osmium::Location loc(-0.001, 0.001);
+ 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));
}
+ {
+ const osmium::Location loc(-85.2, -85.2);
+ 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));
+ }
+}
+
+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
index 953fcc7..5454fed 100644
--- a/test/t/geom/test_tile.cpp
+++ b/test/t/geom/test_tile.cpp
@@ -4,6 +4,8 @@
#include <osmium/geom/tile.hpp>
+#include "helper.hpp"
+
#include "test_tile_data.hpp"
TEST_CASE("Tile from x0.0 y0.0 at zoom 0") {
diff --git a/test/t/geom/test_wkb.cpp b/test/t/geom/test_wkb.cpp
index 66dd42e..d4d9228 100644
--- a/test/t/geom/test_wkb.cpp
+++ b/test/t/geom/test_wkb.cpp
@@ -10,28 +10,28 @@ TEST_CASE("WKB geometry factory (byte-order-dependant), points") {
const osmium::Location loc{3.2, 4.2};
SECTION("point") {
- osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex};
+ osmium::geom::WKBFactory<> factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
const std::string wkb{factory.create_point(loc)};
REQUIRE(wkb == "01010000009A99999999990940CDCCCCCCCCCC1040");
}
SECTION("point in web mercator") {
- osmium::geom::WKBFactory<osmium::geom::MercatorProjection> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex};
+ osmium::geom::WKBFactory<osmium::geom::MercatorProjection> factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
const std::string wkb{factory.create_point(loc)};
REQUIRE(wkb == "010100000028706E7BF9BD1541B03E0D93E48F1C41");
}
SECTION("point in ewkb") {
- osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex};
+ osmium::geom::WKBFactory<> factory(osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex);
const std::string wkb{factory.create_point(loc)};
REQUIRE(wkb == "0101000020E61000009A99999999990940CDCCCCCCCCCC1040");
}
SECTION("point in ewkb in web mercator") {
- osmium::geom::WKBFactory<osmium::geom::MercatorProjection> factory{osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex};
+ osmium::geom::WKBFactory<osmium::geom::MercatorProjection> factory(osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex);
const std::string wkb{factory.create_point(loc)};
REQUIRE(wkb == "0101000020110F000028706E7BF9BD1541B03E0D93E48F1C41");
@@ -44,7 +44,7 @@ TEST_CASE("WKB geometry factory (byte-order-dependant)") {
osmium::memory::Buffer buffer{10000};
SECTION("linestring") {
- osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex};
+ osmium::geom::WKBFactory<> factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
const auto& wnl = create_test_wnl_okay(buffer);
{
@@ -69,7 +69,7 @@ TEST_CASE("WKB geometry factory (byte-order-dependant)") {
}
SECTION("linestring as ewkb") {
- osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex};
+ osmium::geom::WKBFactory<> factory(osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex);
const auto& wnl = create_test_wnl_okay(buffer);
@@ -78,7 +78,7 @@ TEST_CASE("WKB geometry factory (byte-order-dependant)") {
}
SECTION("linestring with two same locations") {
- osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex};
+ osmium::geom::WKBFactory<> factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
const auto& wnl = create_test_wnl_same_location(buffer);
@@ -102,7 +102,7 @@ TEST_CASE("WKB geometry factory (byte-order-dependant)") {
}
SECTION("linestring with undefined location") {
- osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex};
+ osmium::geom::WKBFactory<> factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
const auto& wnl = create_test_wnl_undefined_location(buffer);
@@ -115,7 +115,7 @@ TEST_CASE("WKB geometry factory (byte-order-dependant)") {
TEST_CASE("WKB geometry (byte-order-independent)") {
- osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex};
+ osmium::geom::WKBFactory<> factory(osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex);
SECTION("empty point") {
REQUIRE_THROWS_AS(factory.create_point(osmium::Location{}), osmium::invalid_location);
diff --git a/test/t/geom/wnl_helper.hpp b/test/t/geom/wnl_helper.hpp
index 68de4c3..91ac114 100644
--- a/test/t/geom/wnl_helper.hpp
+++ b/test/t/geom/wnl_helper.hpp
@@ -6,7 +6,7 @@
using namespace osmium::builder::attr;
inline const osmium::WayNodeList& create_test_wnl_okay(osmium::memory::Buffer& buffer) {
- const auto pos = osmium::builder::add_way_node_list(buffer, _nodes({
+ auto pos = osmium::builder::add_way_node_list(buffer, _nodes({
{1, {3.2, 4.2}},
{3, {3.5, 4.7}},
{4, {3.5, 4.7}},
@@ -25,7 +25,7 @@ inline const osmium::WayNodeList& create_test_wnl_empty(osmium::memory::Buffer&
}
inline const osmium::WayNodeList& create_test_wnl_same_location(osmium::memory::Buffer& buffer) {
- const auto pos = osmium::builder::add_way_node_list(buffer, _nodes({
+ auto pos = osmium::builder::add_way_node_list(buffer, _nodes({
{1, {3.5, 4.7}},
{2, {3.5, 4.7}}
}));
@@ -34,7 +34,7 @@ inline const osmium::WayNodeList& create_test_wnl_same_location(osmium::memory::
}
inline const osmium::WayNodeList& create_test_wnl_undefined_location(osmium::memory::Buffer& buffer) {
- const auto pos = osmium::builder::add_way_node_list(buffer, _nodes({
+ auto pos = osmium::builder::add_way_node_list(buffer, _nodes({
{1, {3.5, 4.7}},
{2, osmium::Location()}
}));
diff --git a/test/t/index/test_id_set.cpp b/test/t/index/test_id_set.cpp
deleted file mode 100644
index 4c24447..0000000
--- a/test/t/index/test_id_set.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-
-#include "catch.hpp"
-
-#include <osmium/index/id_set.hpp>
-#include <osmium/osm/types.hpp>
-
-TEST_CASE("Basic functionality of IdSetDense") {
- osmium::index::IdSetDense<osmium::unsigned_object_id_type> s;
-
- REQUIRE_FALSE(s.get(17));
- REQUIRE_FALSE(s.get(28));
- REQUIRE(s.empty());
- REQUIRE(s.size() == 0);
-
- s.set(17);
- REQUIRE(s.get(17));
- REQUIRE_FALSE(s.get(28));
- REQUIRE_FALSE(s.empty());
- REQUIRE(s.size() == 1);
-
- s.set(28);
- REQUIRE(s.get(17));
- REQUIRE(s.get(28));
- REQUIRE_FALSE(s.empty());
- REQUIRE(s.size() == 2);
-
- s.set(17);
- REQUIRE(s.get(17));
- REQUIRE(s.size() == 2);
-
- REQUIRE_FALSE(s.check_and_set(17));
- REQUIRE(s.get(17));
- REQUIRE(s.size() == 2);
-
- s.unset(17);
- REQUIRE_FALSE(s.get(17));
- REQUIRE(s.size() == 1);
-
- REQUIRE(s.check_and_set(32));
- REQUIRE(s.get(32));
- REQUIRE(s.size() == 2);
-
- s.clear();
- REQUIRE(s.empty());
- REQUIRE(s.size() == 0);
-}
-
-TEST_CASE("Iterating over IdSetDense") {
- osmium::index::IdSetDense<osmium::unsigned_object_id_type> s;
- s.set(7);
- s.set(35);
- s.set(35);
- s.set(20);
- s.set(1LL << 33);
- s.set(21);
- s.set((1LL << 27) + 13);
-
- REQUIRE(s.size() == 6);
-
- auto it = s.begin();
- REQUIRE(it != s.end());
- REQUIRE(*it == 7);
- ++it;
- REQUIRE(it != s.end());
- REQUIRE(*it == 20);
- ++it;
- REQUIRE(it != s.end());
- REQUIRE(*it == 21);
- ++it;
- REQUIRE(it != s.end());
- REQUIRE(*it == 35);
- ++it;
- REQUIRE(it != s.end());
- REQUIRE(*it == (1LL << 27) + 13);
- ++it;
- REQUIRE(it != s.end());
- REQUIRE(*it == 1LL << 33);
- ++it;
- REQUIRE(it == s.end());
-}
-
-TEST_CASE("Test with larger Ids") {
- osmium::index::IdSetDense<osmium::unsigned_object_id_type> s;
-
- const osmium::unsigned_object_id_type start = 25;
- const osmium::unsigned_object_id_type end = 100000000;
- const osmium::unsigned_object_id_type step = 123456;
-
- for (osmium::unsigned_object_id_type i = start; i < end; i += step) {
- s.set(i);
- }
-
- for (osmium::unsigned_object_id_type i = start; i < end; i += step) {
- REQUIRE(s.get(i));
- REQUIRE_FALSE(s.get(i + 1));
- }
-}
-
-TEST_CASE("Large gap") {
- osmium::index::IdSetDense<osmium::unsigned_object_id_type> s;
-
- s.set(3);
- s.set(1 << 30);
-
- REQUIRE(s.get(1 << 30));
- REQUIRE_FALSE(s.get(1 << 29));
-}
-
-TEST_CASE("Basic functionality of IdSetSmall") {
- osmium::index::IdSetSmall<osmium::unsigned_object_id_type> s;
-
- REQUIRE_FALSE(s.get(17));
- REQUIRE_FALSE(s.get(28));
- REQUIRE(s.empty());
-
- s.set(17);
- REQUIRE(s.get(17));
- REQUIRE_FALSE(s.get(28));
- REQUIRE_FALSE(s.empty());
-
- s.set(28);
- REQUIRE(s.get(17));
- REQUIRE(s.get(28));
- REQUIRE_FALSE(s.empty());
-
- s.clear();
- REQUIRE(s.empty());
-}
-
-TEST_CASE("Iterating over IdSetSmall") {
- osmium::index::IdSetSmall<osmium::unsigned_object_id_type> s;
- s.set(7);
- s.set(35);
- s.set(35);
- s.set(20);
- s.set(1LL << 33);
- s.set(21);
- s.set((1LL << 27) + 13);
-
- // needs to be called before size() and iterator will work properly
- s.sort_unique();
-
- REQUIRE(s.size() == 6);
-
- auto it = s.begin();
- REQUIRE(it != s.end());
- REQUIRE(*it == 7);
- ++it;
- REQUIRE(it != s.end());
- REQUIRE(*it == 20);
- ++it;
- REQUIRE(it != s.end());
- REQUIRE(*it == 21);
- ++it;
- REQUIRE(it != s.end());
- REQUIRE(*it == 35);
- ++it;
- REQUIRE(it != s.end());
- REQUIRE(*it == (1LL << 27) + 13);
- ++it;
- REQUIRE(it != s.end());
- REQUIRE(*it == 1LL << 33);
- ++it;
- REQUIRE(it == s.end());
-}
-
diff --git a/test/t/index/test_id_to_location.cpp b/test/t/index/test_id_to_location.cpp
index 36fc074..810ef3b 100644
--- a/test/t/index/test_id_to_location.cpp
+++ b/test/t/index/test_id_to_location.cpp
@@ -15,14 +15,12 @@
#include <osmium/index/node_locations_map.hpp>
-static_assert(osmium::index::empty_value<osmium::Location>() == osmium::Location{}, "Empty value for location is wrong");
-
template <typename TIndex>
void test_func_all(TIndex& index) {
- const osmium::unsigned_object_id_type id1 = 12;
- const osmium::unsigned_object_id_type id2 = 3;
- const osmium::Location loc1{1.2, 4.5};
- const osmium::Location loc2{3.5, -7.2};
+ osmium::unsigned_object_id_type id1 = 12;
+ osmium::unsigned_object_id_type id2 = 3;
+ osmium::Location loc1{1.2, 4.5};
+ osmium::Location loc2{3.5, -7.2};
REQUIRE_THROWS_AS(index.get(id1), osmium::not_found);
@@ -35,16 +33,14 @@ void test_func_all(TIndex& index) {
REQUIRE_THROWS_AS(index.get(1), osmium::not_found);
REQUIRE_THROWS_AS(index.get(5), osmium::not_found);
REQUIRE_THROWS_AS(index.get(100), osmium::not_found);
- REQUIRE_THROWS_WITH(index.get(0), "id 0 not found");
- REQUIRE_THROWS_WITH(index.get(1), "id 1 not found");
}
template <typename TIndex>
void test_func_real(TIndex& index) {
- const osmium::unsigned_object_id_type id1 = 12;
- const osmium::unsigned_object_id_type id2 = 3;
- const osmium::Location loc1{1.2, 4.5};
- const osmium::Location loc2{3.5, -7.2};
+ osmium::unsigned_object_id_type id1 = 12;
+ osmium::unsigned_object_id_type id2 = 3;
+ osmium::Location loc1{1.2, 4.5};
+ osmium::Location loc2{3.5, -7.2};
index.set(id1, loc1);
index.set(id2, loc2);
@@ -70,116 +66,115 @@ void test_func_real(TIndex& index) {
REQUIRE_THROWS_AS(index.get(100), osmium::not_found);
}
-TEST_CASE("Map Id to location: Dummy") {
- using index_type = osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location>;
+TEST_CASE("IdToLocation") {
- index_type index1;
+ SECTION("Dummy") {
+ using index_type = osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location>;
- REQUIRE(0 == index1.size());
- REQUIRE(0 == index1.used_memory());
+ 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());
-}
+ test_func_all<index_type>(index1);
-TEST_CASE("Map Id to location: DenseMemArray") {
- using index_type = osmium::index::map::DenseMemArray<osmium::unsigned_object_id_type, osmium::Location>;
+ REQUIRE(0 == index1.size());
+ REQUIRE(0 == index1.used_memory());
+ }
- index_type index1;
- index1.reserve(1000);
- test_func_all<index_type>(index1);
+ SECTION("DenseMemArray") {
+ using index_type = osmium::index::map::DenseMemArray<osmium::unsigned_object_id_type, osmium::Location>;
- index_type index2;
- index2.reserve(1000);
- test_func_real<index_type>(index2);
-}
+ index_type index1;
+ index1.reserve(1000);
+ test_func_all<index_type>(index1);
+
+ index_type index2;
+ index2.reserve(1000);
+ test_func_real<index_type>(index2);
+ }
#ifdef __linux__
-TEST_CASE("Map Id to location: DenseMmapArray") {
- using index_type = osmium::index::map::DenseMmapArray<osmium::unsigned_object_id_type, osmium::Location>;
+ SECTION("DenseMmapArray") {
+ using index_type = osmium::index::map::DenseMmapArray<osmium::unsigned_object_id_type, osmium::Location>;
- 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
-TEST_CASE("Map Id to location: DenseFileArray") {
- using index_type = osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, osmium::Location>;
+ SECTION("DenseFileArray") {
+ using index_type = osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, osmium::Location>;
- 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
-TEST_CASE("Map Id to location: SparseMemTable") {
- using index_type = osmium::index::map::SparseMemTable<osmium::unsigned_object_id_type, osmium::Location>;
+ SECTION("SparseMemTable") {
+ using index_type = osmium::index::map::SparseMemTable<osmium::unsigned_object_id_type, osmium::Location>;
- 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
-TEST_CASE("Map Id to location: SparseMemMap") {
- using index_type = osmium::index::map::SparseMemMap<osmium::unsigned_object_id_type, osmium::Location>;
+ SECTION("SparseMemMap") {
+ using index_type = osmium::index::map::SparseMemMap<osmium::unsigned_object_id_type, osmium::Location>;
- index_type index1;
- test_func_all<index_type>(index1);
-
- index_type index2;
- test_func_real<index_type>(index2);
-}
+ index_type index1;
+ test_func_all<index_type>(index1);
-TEST_CASE("Map Id to location: SparseMemArray") {
- using index_type = osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location>;
+ index_type index2;
+ test_func_real<index_type>(index2);
+ }
- index_type index1;
+ SECTION("SparseMemArray") {
+ using index_type = osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location>;
- REQUIRE(0 == index1.size());
- REQUIRE(0 == index1.used_memory());
+ index_type index1;
- test_func_all<index_type>(index1);
+ REQUIRE(0 == index1.size());
+ REQUIRE(0 == index1.used_memory());
- REQUIRE(2 == index1.size());
+ test_func_all<index_type>(index1);
- index_type index2;
- test_func_real<index_type>(index2);
-}
+ REQUIRE(2 == index1.size());
-TEST_CASE("Map Id to location: Dynamic map choice") {
- using map_type = osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location>;
- const auto& map_factory = osmium::index::MapFactory<osmium::unsigned_object_id_type, osmium::Location>::instance();
+ index_type index2;
+ test_func_real<index_type>(index2);
+ }
- const std::vector<std::string> map_type_names = map_factory.map_types();
- REQUIRE(map_type_names.size() >= 5);
+ SECTION("Dynamic map choice") {
+ using map_type = osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location>;
+ const auto& map_factory = osmium::index::MapFactory<osmium::unsigned_object_id_type, osmium::Location>::instance();
- REQUIRE_THROWS_AS(map_factory.create_map(""), osmium::map_factory_error);
- REQUIRE_THROWS_AS(map_factory.create_map("does not exist"), osmium::map_factory_error);
- REQUIRE_THROWS_WITH(map_factory.create_map(""), "Need non-empty map type name");
- REQUIRE_THROWS_WITH(map_factory.create_map("does not exist"), "Support for map type 'does not exist' not compiled into this binary");
+ const 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/io/test_compression_factory.cpp b/test/t/io/test_compression_factory.cpp
deleted file mode 100644
index 5428d82..0000000
--- a/test/t/io/test_compression_factory.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-
-#include "catch.hpp"
-
-#include <osmium/io/compression.hpp>
-
-TEST_CASE("Compression factory") {
- const auto& factory = osmium::io::CompressionFactory::instance();
-
- SECTION("compressor") {
- REQUIRE(factory.create_compressor(osmium::io::file_compression::none, -1, osmium::io::fsync::no));
- }
-
- SECTION("decompressor") {
- REQUIRE(factory.create_decompressor(osmium::io::file_compression::none, nullptr, 0));
- }
-
- SECTION("fail on undefined compression") {
- REQUIRE_THROWS_AS({
- factory.create_compressor(osmium::io::file_compression::gzip, -1, osmium::io::fsync::no);
- }, osmium::unsupported_file_format_error);
- REQUIRE_THROWS_WITH({
- factory.create_compressor(osmium::io::file_compression::gzip, -1, osmium::io::fsync::no);
- }, "Support for compression 'gzip' not compiled into this binary");
- }
-
-}
-
diff --git a/test/t/io/test_reader_with_mock_parser.cpp b/test/t/io/test_reader_with_mock_parser.cpp
index b1076cc..c5c9975 100644
--- a/test/t/io/test_reader_with_mock_parser.cpp
+++ b/test/t/io/test_reader_with_mock_parser.cpp
@@ -24,9 +24,9 @@ public:
MockParser(osmium::io::detail::future_string_queue_type& input_queue,
osmium::io::detail::future_buffer_queue_type& output_queue,
std::promise<osmium::io::Header>& header_promise,
- osmium::io::detail::reader_options options,
+ osmium::osm_entity_bits::type read_types,
const std::string& fail_in) :
- Parser(input_queue, output_queue, header_promise, options),
+ Parser(input_queue, output_queue, header_promise, read_types),
m_fail_in(fail_in) {
}
@@ -59,8 +59,8 @@ TEST_CASE("Test Reader using MockParser") {
[&](osmium::io::detail::future_string_queue_type& input_queue,
osmium::io::detail::future_buffer_queue_type& output_queue,
std::promise<osmium::io::Header>& header_promise,
- osmium::io::detail::reader_options options) {
- return std::unique_ptr<osmium::io::detail::Parser>(new MockParser(input_queue, output_queue, header_promise, options, fail_in));
+ osmium::osm_entity_bits::type read_which_entities) {
+ return std::unique_ptr<osmium::io::detail::Parser>(new MockParser(input_queue, output_queue, header_promise, read_which_entities, fail_in));
});
SECTION("no failure") {
diff --git a/test/t/osm/test_entity_bits.cpp b/test/t/osm/test_entity_bits.cpp
deleted file mode 100644
index a124fa3..0000000
--- a/test/t/osm/test_entity_bits.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "catch.hpp"
-
-#include <osmium/osm/entity_bits.hpp>
-
-static_assert((osmium::osm_entity_bits::node
- |osmium::osm_entity_bits::way
- |osmium::osm_entity_bits::relation)
- == osmium::osm_entity_bits::nwr, "entity_bits nwr failed");
-
-static_assert((osmium::osm_entity_bits::node
- |osmium::osm_entity_bits::way
- |osmium::osm_entity_bits::relation
- |osmium::osm_entity_bits::area)
- == osmium::osm_entity_bits::nwra, "entity_bits nwra failed");
-
-static_assert((osmium::osm_entity_bits::nwra
- |osmium::osm_entity_bits::changeset)
- == osmium::osm_entity_bits::all, "entity_bits all failed");
-
-static_assert((osmium::osm_entity_bits::all
- &osmium::osm_entity_bits::node)
- == osmium::osm_entity_bits::node, "entity_bits node failed");
-
-static_assert((~osmium::osm_entity_bits::all) == osmium::osm_entity_bits::nothing, "entity_bits nothing is the inverse of all");
-static_assert((~osmium::osm_entity_bits::nothing) == osmium::osm_entity_bits::all, "entity_bits all is the inverse of nothing");
-static_assert((~osmium::osm_entity_bits::changeset) == osmium::osm_entity_bits::nwra, "entity_bits nwra is the inverse of changeset");
-
-TEST_CASE("Bitwise 'and' and 'or' on entity bits") {
- 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::area;
- REQUIRE(entities == osmium::osm_entity_bits::object);
-
- REQUIRE_FALSE((entities & osmium::osm_entity_bits::changeset));
-
- entities &= osmium::osm_entity_bits::node;
- REQUIRE((entities & osmium::osm_entity_bits::node));
- REQUIRE_FALSE((entities & osmium::osm_entity_bits::way));
- REQUIRE(entities == osmium::osm_entity_bits::node);
-}
-
-TEST_CASE("Bitwise 'not' on entity bits") {
- REQUIRE(~osmium::osm_entity_bits::all == osmium::osm_entity_bits::nothing);
- REQUIRE(~osmium::osm_entity_bits::nothing == osmium::osm_entity_bits::all);
- REQUIRE(~osmium::osm_entity_bits::node == (osmium::osm_entity_bits::way | osmium::osm_entity_bits::relation | osmium::osm_entity_bits::area | osmium::osm_entity_bits::changeset));
- REQUIRE(~osmium::osm_entity_bits::nwr == (osmium::osm_entity_bits::area | osmium::osm_entity_bits::changeset));
- REQUIRE(~osmium::osm_entity_bits::nwra == osmium::osm_entity_bits::changeset);
-}
-
-TEST_CASE("Converting item types to entity bits") {
- REQUIRE(osmium::osm_entity_bits::nothing == osmium::osm_entity_bits::from_item_type(osmium::item_type::undefined));
- 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));
-}
-
--
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