Upgrade libosmium to v2.15.6

This commit is contained in:
Desone Burns II 2020-11-17 14:59:06 -07:00
parent 98fd17589d
commit dfc1bfc27e
319 changed files with 6268 additions and 3946 deletions

View File

@ -1,14 +1,22 @@
---
Checks: '*,-android-cloexec-*,-cert-dcl21-cpp,-cert-err58-cpp,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-type-vararg,-fuchsia-*,-google-runtime-references,-hicpp-invalid-access-moved,-hicpp-no-array-decay,-hicpp-no-assembler,-hicpp-vararg,-misc-macro-parentheses,-misc-unused-parameters,-modernize-make-unique,-modernize-raw-string-literal,-readability-avoid-const-params-in-decls,-readability-implicit-bool-cast,-readability-implicit-bool-conversion'
Checks: '*,-android-cloexec-*,-bugprone-branch-clone,-bugprone-macro-parentheses,-cert-dcl21-cpp,-cert-err58-cpp,-clang-analyzer-optin.cplusplus.VirtualCall,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-macro-usage,-cppcoreguidelines-non-private-member-variables-in-classes,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-type-vararg,-fuchsia-*,-google-runtime-references,-hicpp-avoid-c-arrays,-hicpp-invalid-access-moved,-hicpp-no-array-decay,-hicpp-no-assembler,-hicpp-vararg,-misc-macro-parentheses,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-avoid-c-arrays,-modernize-make-unique,-modernize-raw-string-literal,-modernize-use-trailing-return-type,-readability-avoid-const-params-in-decls,-readability-implicit-bool-cast,-readability-implicit-bool-conversion,-readability-magic-numbers'
#
# For a list of check options, see:
# http://clang.llvm.org/extra/clang-tidy/checks/list.html
# https://clang.llvm.org/extra/clang-tidy/checks/list.html
#
# Disabled checks:
#
# android-cloexec-*
# O_CLOEXEC isn't available on Windows making this non-portable.
#
# bugprone-branch-clone
# Nice idea but collides but with switch statements we'll need to use
# fall-throughs to fix this, which is also bad.
#
# bugprone-macro-parentheses
# False positive in the only place where it reports something and
# disabling locally doesn't work.
#
# cert-dcl21-cpp
# It is unclear whether this is still a good recommendation in modern C++.
#
@ -16,6 +24,22 @@ Checks: '*,-android-cloexec-*,-cert-dcl21-cpp,-cert-err58-cpp,-cppcoreguidelines
# Used in several singelton factory functions. I don't know of a better
# way to do this and it is rather unlikely that this will be a problem.
#
# clang-analyzer-optin.cplusplus.VirtualCall
# Disable a warning we get from the Catch test framework.
#
# cppcoreguidelines-avoid-c-arrays
# Alias for modernize-avoid-c-arrays.
#
# cppcoreguidelines-avoid-magic-numbers
# Generally good advice, but there are too many places where this is
# useful, for instance in tests.
#
# cppcoreguidelines-macro-usage
# There are cases where we actually need macros.
#
# cppcoreguidelines-non-private-member-variables-in-classes
# Alias for misc-non-private-member-variables-in-classes
#
# cppcoreguidelines-owning-memory
# Don't want to add dependency on gsl library.
#
@ -48,6 +72,9 @@ Checks: '*,-android-cloexec-*,-cert-dcl21-cpp,-cert-err58-cpp,-cppcoreguidelines
# This is just a matter of preference, and we can't change the interfaces
# now anyways.
#
# hicpp-avoid-c-arrays
# Alias for modernize-avoid-c-arrays.
#
# hicpp-invalid-access-moved
# Creates false positives.
#
@ -61,13 +88,21 @@ Checks: '*,-android-cloexec-*,-cert-dcl21-cpp,-cert-err58-cpp,-cppcoreguidelines
# Too strict, sometimes calling vararg functions is necessary.
#
# misc-macro-parentheses
# False positive in the only place where it reports something and
# disabling locally doesn't work.
# Old name for bugprone-macro-parentheses.
#
# misc-non-private-member-variables-in-classes
# Reports this also for structs, which doesn't make any sense. There is
# an option "IgnoreClassesWithAllMemberVariablesBeingPublic" which should
# disable this, but it didn't work for me.
#
# misc-unused-parameters
# Can't be fixed, because then Doxygen will complain. (In file
# include/osmium/area/problem_reporter.hpp).
#
# modernize-avoid-c-arrays
# Makes sense for some array, but especially for char arrays using
# std::array isn't a good solution.
#
# modernize-make-unique
# This is a C++11 library and C++ doesn't have std::make_unique.
#
@ -75,6 +110,9 @@ Checks: '*,-android-cloexec-*,-cert-dcl21-cpp,-cert-err58-cpp,-cppcoreguidelines
# Readability isn't that much better, arguably worse because of the new
# syntax.
#
# modernize-use-trailing-return-type
# I am not quite that modern.
#
# readability-avoid-const-params-in-decls
# This is header only library, so the declaration and implementation are
# often the same and we want to have the const in implementations.
@ -85,6 +123,9 @@ Checks: '*,-android-cloexec-*,-cert-dcl21-cpp,-cert-err58-cpp,-cppcoreguidelines
# readability-implicit-bool-conversion
# I don't think this makes the code more readable.
#
# readability-magic-numbers
# Alias for cppcoreguidelines-avoid-magic-numbers.
#
#WarningsAsErrors: '*'
HeaderFilterRegex: '\/include\/osmium\/.*'
...

View File

@ -4,12 +4,12 @@
#
#-----------------------------------------------------------------------------
os: linux
dist: xenial
language: generic
sudo: false
dist: trusty
#-----------------------------------------------------------------------------
cache:
@ -32,190 +32,171 @@ addons_shortcuts:
packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-3.5']
addons_clang38: &clang38
apt:
sources: [ 'ubuntu-toolchain-r-test', 'boost-latest' ]
packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-3.8']
packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-3.8']
addons_clang39: &clang39
apt:
sources: [ 'ubuntu-toolchain-r-test', 'boost-latest' ]
packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-3.9']
addons_clang40: &clang40
apt:
sources: [ 'ubuntu-toolchain-r-test', 'boost-latest', 'llvm-toolchain-trusty-4.0' ]
packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-4.0']
packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-3.9']
addons_clang50: &clang50
apt:
sources: [ 'ubuntu-toolchain-r-test', 'boost-latest', 'llvm-toolchain-trusty-5.0' ]
packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-5.0', 'g++-6', 'gcc-6']
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-5.0', 'g++-6', 'gcc-6']
addons_clang60: &clang60
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-6.0', 'g++-6', 'gcc-6']
addons_clang7: &clang7
apt:
packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-7' ]
addons_gcc48: &gcc48
apt:
sources: [ 'ubuntu-toolchain-r-test', 'boost-latest' ]
packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-4.8', 'gcc-4.8' ]
packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-4.8', 'gcc-4.8' ]
addons_gcc49: &gcc49
apt:
sources: [ 'ubuntu-toolchain-r-test', 'boost-latest' ]
packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-4.9', 'gcc-4.9' ]
packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-4.9', 'gcc-4.9' ]
addons_gcc5: &gcc5
apt:
sources: [ 'ubuntu-toolchain-r-test', 'boost-latest' ]
packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-5', 'gcc-5' ]
packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-5', 'gcc-5' ]
addons_gcc6: &gcc6
apt:
sources: [ 'ubuntu-toolchain-r-test', 'boost-latest' ]
packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-6', 'gcc-6' ]
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-6', 'gcc-6' ]
addons_gcc7: &gcc7
apt:
packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin' ]
#-----------------------------------------------------------------------------
matrix:
addons:
homebrew:
packages:
- cmake
- boost
- google-sparsehash
- gdal
update: true
#-----------------------------------------------------------------------------
jobs:
include:
# 1/ Linux Clang Builds
- os: linux
compiler: linux-clang35-release
env: CC='clang-3.5' CXX='clang++-3.5' BUILD_TYPE='Release'
addons: *clang35
# Linux Clang Builds
- os: linux
compiler: linux-clang35-dev
env: CC='clang-3.5' CXX='clang++-3.5' BUILD_TYPE='Dev'
addons: *clang35
- os: linux
compiler: linux-clang38-release
env: CC='clang-3.8' CXX='clang++-3.8' BUILD_TYPE='Release'
addons: *clang38
dist: trusty
- os: linux
compiler: linux-clang38-dev
env: CC='clang-3.8' CXX='clang++-3.8' BUILD_TYPE='Dev'
addons: *clang38
- os: linux
compiler: linux-clang39-release
env: CC='clang-3.9' CXX='clang++-3.9' BUILD_TYPE='Release'
addons: *clang39
- os: linux
compiler: linux-clang39-dev
env: CC='clang-3.9' CXX='clang++-3.9' BUILD_TYPE='Dev'
addons: *clang39
- os: linux
compiler: linux-clang40-release
env: CC='clang-4.0' CXX='clang++-4.0' BUILD_TYPE='Release'
addons: *clang40
- os: linux
compiler: linux-clang40-dev
env: CC='clang-4.0' CXX='clang++-4.0' BUILD_TYPE='Dev'
addons: *clang40
- os: linux
compiler: linux-clang50-release
env: CC='clang-5.0' CXX='clang++-5.0' BUILD_TYPE='Release'
addons: *clang50
- os: linux
compiler: linux-clang50-dev
env: CC='clang-5.0' CXX='clang++-5.0' BUILD_TYPE='Dev'
addons: *clang50
# Disabled because it creates false-positives on the old travis systems
# - os: linux
# compiler: linux-clang50-debug
# env: CC='clang-5.0' CXX='clang++-5.0' BUILD_TYPE='Debug'
# CXXFLAGS="-fsanitize=address,undefined,integer -fno-sanitize-recover=all -fno-omit-frame-pointer"
# LDFLAGS="-fsanitize=address,undefined,integer"
# # LSAN doesn't work on container-based system
# sudo: required
# addons: *clang50
# 2/ Linux GCC Builds
- os: linux
compiler: linux-gcc48-release
env: CC='gcc-4.8' CXX='g++-4.8' BUILD_TYPE='Release'
CXXFLAGS='-Wno-return-type'
addons: *gcc48
compiler: linux-clang60-dev
env: CC='clang-6.0' CXX='clang++-6.0' BUILD_TYPE='Dev'
addons: *clang60
- os: linux
compiler: linux-clang60-debug
env: CC='clang-6.0' CXX='clang++-6.0' BUILD_TYPE='Debug'
CXXFLAGS="-fsanitize=address,undefined,integer -fno-sanitize-recover=all -fno-omit-frame-pointer"
LDFLAGS="-fsanitize=address,undefined,integer"
addons: *clang60
- os: linux
compiler: linux-clang60-release
env: CC='clang-6.0' CXX='clang++-6.0' BUILD_TYPE='Release'
addons: *clang60
- os: linux
compiler: linux-clang7-debug
env: CC='clang-7' CXX='clang++-7' BUILD_TYPE='Debug'
CXXFLAGS="-fsanitize=address,undefined,integer -fno-sanitize-recover=all -fno-omit-frame-pointer"
LDFLAGS="-fsanitize=address,undefined,integer"
addons: *clang7
dist: bionic
- os: linux
compiler: linux-clang7-release
env: CC='clang-7' CXX='clang++-7' BUILD_TYPE='Release'
addons: *clang7
dist: bionic
# Linux GCC Builds
- os: linux
compiler: linux-gcc48-dev
env: CC='gcc-4.8' CXX='g++-4.8' BUILD_TYPE='Dev'
CXXFLAGS='-Wno-return-type'
addons: *gcc48
- os: linux
compiler: linux-gcc49-release
env: CC='gcc-4.9' CXX='g++-4.9' BUILD_TYPE='Release'
addons: *gcc49
- os: linux
compiler: linux-gcc49-dev
env: CC='gcc-4.9' CXX='g++-4.9' BUILD_TYPE='Dev'
addons: *gcc49
- os: linux
compiler: linux-gcc5-release
env: CC='gcc-5' CXX='g++-5' BUILD_TYPE='Release'
addons: *gcc5
- os: linux
compiler: linux-gcc5-dev
env: CC='gcc-5' CXX='g++-5' BUILD_TYPE='Dev'
addons: *gcc5
- os: linux
compiler: linux-gcc6-release
env: CC='gcc-6' CXX='g++-6' BUILD_TYPE='Release'
addons: *gcc6
- os: linux
compiler: linux-gcc6-dev
env: CC='gcc-6' CXX='g++-6' BUILD_TYPE='Dev'
addons: *gcc6
- os: linux
compiler: linux-gcc6-coverage
env: CC='gcc-6' CXX='g++-6' BUILD_TYPE='Coverage'
addons: *gcc6
compiler: linux-gcc7-dev
env: CC='gcc-7' CXX='g++-7' BUILD_TYPE='Dev'
addons: *gcc7
dist: bionic
# 3/ OSX Clang Builds
- os: osx
osx_image: xcode6.4
compiler: xcode64-clang-release
env: CC='clang' CXX='clang++' BUILD_TYPE='Release'
- os: linux
compiler: linux-gcc7-coverage
env: CC='gcc-7' CXX='g++-7' BUILD_TYPE='Coverage'
addons: *gcc7
dist: bionic
- os: linux
compiler: linux-gcc7-release
env: CC='gcc-7' CXX='g++-7' BUILD_TYPE='Release'
addons: *gcc7
dist: bionic
# OSX Clang Builds
- os: osx
osx_image: xcode6.4
compiler: xcode64-clang-dev
osx_image: xcode9.4
compiler: xcode94-clang-dev
env: CC='clang' CXX='clang++' BUILD_TYPE='Dev'
- os: osx
osx_image: xcode7
compiler: xcode7-clang-release
env: CC='clang' CXX='clang++' BUILD_TYPE='Release'
- os: osx
osx_image: xcode7
compiler: xcode7-clang-dev
osx_image: xcode10.2
compiler: xcode10-clang-dev
env: CC='clang' CXX='clang++' BUILD_TYPE='Dev'
- os: osx
osx_image: xcode8.3
compiler: xcode8-clang-release
env: CC='clang' CXX='clang++' BUILD_TYPE='Release'
osx_image: xcode11
compiler: xcode11-clang-dev
env: CC='clang' CXX='clang++' BUILD_TYPE='Dev'
- os: osx
osx_image: xcode8.3
compiler: xcode8-clang-dev
env: CC='clang' CXX='clang++' BUILD_TYPE='Dev'
osx_image: xcode11
compiler: xcode11-clang-release
env: CC='clang' CXX='clang++' BUILD_TYPE='Release'
install:
- git clone --quiet --depth 1 https://github.com/mapbox/protozero.git ../protozero
- |
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
brew remove gdal
brew install cmake boost google-sparsehash gdal || true
fi
- cmake --version
before_script:

View File

@ -2,7 +2,7 @@
#
# Configuration for YouCompleteMe Vim plugin
#
# http://valloric.github.io/YouCompleteMe/
# https://valloric.github.io/YouCompleteMe/
#
#-----------------------------------------------------------------------------

View File

@ -13,6 +13,215 @@ This project adheres to [Semantic Versioning](https://semver.org/).
### Fixed
## [2.15.6] - 2020-06-27
### Added
* Add `IdSetSmall::merge_sorted` function.
### Changed
* Little optimization for IdSetSmall: Don't add the same id twice in a row.
### Fixed
* Do not build areas with "recursion depth > 20". This happens when there
are complex multipolygon with many rings touching in single points. This
is a quick fix that hopefully keeps us going until we find a better
solution.
## [2.15.5] - 2020-04-21
### Added
* Additional constructor for `builder::attr::member_type(_string)` taking
char type making it even easier to generate test data.
* Allow single C string or `std::string` as argument for `builder::attr::_tag`.
Must contain key and value separated by the equal sign.
* New `builder::attr::_t()` function to set tags from comma-separated string.
* New `nwr_array` iterator.
* Support for the PROJ library has now been declared deprecated. The old
PROJ API (up to version PROJ 6) is currently still available, but will
be removed in a future version. Support for the new PROJ API will not be
in libosmium. See https://github.com/osmcode/osmium-proj for some code
that might help you if you need this.
### Changed
* Check how much space is available in file system before resizing memory
mapped file (not on Windows). This means we can, at least in some cases,
show an error message instead of crashing the program.
### Fixed
* Parsing coordinates in PBF files did not work correctly if an lat/lon
offset was specified (which almost never happens).
* Make OPL parser more strict: Attributes can only be specified once.
* Do not close stdout after writing OSM file to it.
## [2.15.4] - 2019-11-28
### Added
* Add osmium::Options::empty() for consistency with STL containers.
### Fixed
* Massive reduction of memory consumption in area assembly code. For some
very complex polygons memory usage can drop from multiple gigabytes to just
megabytes.
## [2.15.3] - 2019-09-16
### Added
* New header option "sorting" when reading and writing PBFs. If the header
option "sorting" is set to `Type_then_ID`, the optional header property
`Sort.Type_then_ID` is set on writing to PBF files. When reading PBF files
with this header property, the "sorting" header option is set accordingly.
### Fixed
* Do not propagate C++ exception through C code. We are using the Expat
XML parser, a C library. It calls callbacks in our code. When those
callbacks throw, the exception was propagated through the C code. This
did work in the tests, but that behaviour isn't guaranteed (C++
standard says it is implementation defined). This fixes it by catching
the exception and rethrowing it later.
## [2.15.2] - 2019-08-16
### Added
* Instead of handler classes, the `apply` function can now also take
lambdas (or objects from classes implementing `operator()`).
* Add swap, copy constructor and assignment operator to IdSetDense.
### Changed
* Enable use of the old proj API in proj version 6. This is a stopgap
solution until we find a better one.
* Better error messages when there is an error parsing a timestamp.
* Cleaned up a lot of code based on clang-tidy warnings.
* Ignore <bbox> or <bounds> subelement of <way> or <relation>. <bounds>
elements are created by Overpass API as subelements of ways or relations
when the "out bb" format is used. <bbox> subelements turn up in files
downloaded from http://download.openstreetmap.fr/replication . Libosmium
used to throw an error like "Unknown element in <way>: bbox". With this
commit, these subelements are ignored, ie. there is no error any more,
but the data is not read.
* Add swap, copy constructor and assignment operator to IdSetDense.
* Update included catch.hpp to 1.12.2.
* Retire use of `OSMIUM_NORETURN` macro. Use `[[noreturn]]` instead.
### Fixed
* Do not build areas with more than 100 locations where rings touch.
Places where rings touch are unusual for normal multipolygons and the
algorithm in libosmium that assembles multipolygons does not handle
them well. If there are too many touching points it becomes very slow.
This is not a problem for almost all multipolygons. As I am writing
this there are only three relations in the OSM database with more than
100 touching points, all of them rather weird boundaries in the US.
With this commit libosmium will simply ignore those areas to keep the
processing speed within reasonable bounds.
## [2.15.1] - 2019-02-26
### Added
* More tests.
* CMake config: also find clang-tidy-7.
### Changed
* Example and benchmark programs now don't crash with exceptions any more
but report them properly.
### Fixed
* Compile with NDEBUG in RelWithDebInfo mode.
* Correctly throw exception in `multimap::dump_as_list()`.
* Integer truncation on 32 bit systems in `MemoryUsage`.
* Exception specification on some functions.
* Forwarding references that might have hidden copy/move constructors.
## [2.15.0] - 2018-12-07
### Added
* Function `dump_as_array()` to dump sparse array indexes.
* Set the `xml_josm_upload` header option when reading XML files.
* New function `OSMObject::remove_tags()` marks tags on OSM objects as
removed.
* More tests.
### Changed
* When reading OSM files Libosmium now has less memory overhead, especially
when reading PBF files. This works by using more, but smaller buffers.
* The `TagsFilter` class is now based on the `TagsFilterBase` template
class which allows setting the result type. This allows the filter to
return more data depending on the rule that matched.
* Use enums for many constants instead of (static) const(expr) variables.
* Make `chunk_bits` in `IdSetDense` configurable.
* Hardcode `%lld` format instead of using `<cinttypes>` PRI macro.
* Update included gdalcpp to version 1.2.0.
### Fixed
* The gzip/bzip2 compression code was overhauled and is better tested now.
This fixes some bugs on Windows.
## [2.14.2] - 2018-07-23
### Fixed
* PBF reader and writer depended on byte order of system architecture.
* Removed an unreliable test that didn't work on some architectures.
## [2.14.1] - 2018-07-23
### Changed
* Libosmium now needs the newest Protozero version 1.6.3.
* Removes dependency on the utfcpp library for conversions between Unicode
code points and UTF-8. We have our own functions for this now. This also
gives us more control on where errors are thrown in this code.
* Add support for using the CRC32 implementation from the zlib library in
addition to the one from Boost. It is significantly faster and means we
have one less dependency, because zlib is needed anyway in almost all
programs using Osmium due to its use in the PBF format. Set macro
`OSMIUM_TEST_CRC_USE_BOOST` before compiling the tests, if you want to
run the tests with the boost library code, otherwise it will use the
zlib code. Note that to use this you have to change your software slightly,
see the documentation of the `CRC_zlib` class for details.
* Add a `clear_user()` function to OSMObject and Changeset which allows
removing the user name of an entity without re-creating it in a new buffer.
* In Osmium the 0 value of the Timestamp is used to denote the "invalid"
Timestamp, and its output using the `to_iso()` function is the empty
string. But this is the wrong output for OSM XML files, where a
timestamp that's not set should still be output as
1970-01-01T00:00:00Z. This version introduces a new `to_is_all()`
function which will do this and uses that function in the XML writer.
* Use `protozero::byteswap_inplace` instead of `htonl`/`ntohl`. Makes the
code simpler and also works on Windows.
* Marked `MultipolygonCollector` class as deprecated. Use the
`MultipolygonManager` class introduced in 2.13.0 instead.
* Lots of code cleanups especially around `assert`s. Libosmium checks out
clean with `clang-tidy` now. Some documentation updates.
### Fixed
* Fix compilation error when `fileno()` is a macro (as in OpenBSD 6.3).
* Make `Box` output consistent with the output of a single `Location`
and avoids problems with some locales.
## [2.14.0] - 2018-03-31
### Added
@ -823,7 +1032,16 @@ This project adheres to [Semantic Versioning](https://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.14.0...HEAD
[unreleased]: https://github.com/osmcode/libosmium/compare/v2.15.6...HEAD
[2.15.6]: https://github.com/osmcode/libosmium/compare/v2.15.5...v2.15.6
[2.15.5]: https://github.com/osmcode/libosmium/compare/v2.15.4...v2.15.5
[2.15.4]: https://github.com/osmcode/libosmium/compare/v2.15.3...v2.15.4
[2.15.3]: https://github.com/osmcode/libosmium/compare/v2.15.2...v2.15.3
[2.15.2]: https://github.com/osmcode/libosmium/compare/v2.15.1...v2.15.2
[2.15.1]: https://github.com/osmcode/libosmium/compare/v2.15.0...v2.15.1
[2.15.0]: https://github.com/osmcode/libosmium/compare/v2.14.2...v2.15.0
[2.14.2]: https://github.com/osmcode/libosmium/compare/v2.14.1...v2.14.2
[2.14.1]: https://github.com/osmcode/libosmium/compare/v2.14.0...v2.14.1
[2.14.0]: https://github.com/osmcode/libosmium/compare/v2.13.1...v2.14.0
[2.13.1]: https://github.com/osmcode/libosmium/compare/v2.13.0...v2.13.1
[2.13.0]: https://github.com/osmcode/libosmium/compare/v2.12.2...v2.13.0

View File

@ -12,20 +12,35 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
#-----------------------------------------------------------------------------
#
# Project version
# Configurations
#
#-----------------------------------------------------------------------------
set(CMAKE_CXX_FLAGS_COVERAGE
"-g -O0 -fno-inline-functions -fno-inline --coverage ${extra_coverage_flags_}"
CACHE STRING "Flags used by the compiler during coverage builds.")
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
"--coverage"
CACHE STRING "Flags used by the linker during coverage builds.")
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel;Dev;Coverage"
CACHE STRING
"List of available configuration types"
FORCE)
#-----------------------------------------------------------------------------
#
# Project version
#
#-----------------------------------------------------------------------------
project(libosmium)
set(LIBOSMIUM_VERSION_MAJOR 2)
set(LIBOSMIUM_VERSION_MINOR 14)
set(LIBOSMIUM_VERSION_PATCH 0)
set(LIBOSMIUM_VERSION_MINOR 15)
set(LIBOSMIUM_VERSION_PATCH 6)
set(LIBOSMIUM_VERSION
"${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}")
@ -62,7 +77,6 @@ option(BUILD_BENCHMARKS "compile benchmark programs" ${dev_build})
option(BUILD_DATA_TESTS "compile data tests, please run them with ctest" ${data_test_build})
option(INSTALL_GDALCPP "also install gdalcpp headers" OFF)
option(INSTALL_UTFCPP "also install utfcpp headers" OFF)
option(WITH_PROFILING "add flags needed for profiling" OFF)
@ -101,14 +115,6 @@ endif()
# set(extra_coverage_flags_ "-fkeep-inline-functions")
#endif()
set(CMAKE_CXX_FLAGS_COVERAGE
"-g -O0 -fno-inline-functions -fno-inline --coverage ${extra_coverage_flags_}"
CACHE STRING "Flags used by the compiler during coverage builds.")
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
"--coverage"
CACHE STRING "Flags used by the linker during coverage builds.")
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
if(BUILD_EXAMPLES OR BUILD_HEADERS OR BUILD_BENCHMARKS)
message(WARNING "Coverage builds don't work for anything but the tests")
@ -200,11 +206,13 @@ endif()
#
#-----------------------------------------------------------------------------
if(MSVC)
set(USUAL_COMPILE_OPTIONS "/Ox")
set(DEV_COMPILE_OPTIONS "/Ox")
set(RWD_COMPILE_OPTIONS "/Ox /DNDEBUG")
# do not show warnings caused by missing .pdb files for libraries
set(USUAL_LINK_OPTIONS "/debug /ignore:4099")
else()
set(USUAL_COMPILE_OPTIONS "-O3 -g")
set(DEV_COMPILE_OPTIONS "-O3 -g")
set(RWD_COMPILE_OPTIONS "-O3 -g -DNDEBUG")
set(USUAL_LINK_OPTIONS "")
endif()
@ -212,7 +220,7 @@ if(WIN32)
add_definitions(-DWIN32 -D_WIN32 -DMSWIN32 -DBGDWIN32)
endif()
set(CMAKE_CXX_FLAGS_DEV "${USUAL_COMPILE_OPTIONS}"
set(CMAKE_CXX_FLAGS_DEV "${DEV_COMPILE_OPTIONS}"
CACHE STRING "Flags used by the compiler during developer builds."
FORCE)
@ -224,7 +232,7 @@ mark_as_advanced(
CMAKE_EXE_LINKER_FLAGS_DEV
)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${USUAL_COMPILE_OPTIONS}"
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${RWD_COMPILE_OPTIONS}"
CACHE STRING "Flags used by the compiler during RELWITHDEBINFO builds."
FORCE)
@ -397,7 +405,7 @@ if(BUILD_HEADERS)
# Create a dummy .cpp file that includes the header file we want to
# check.
set(DUMMYCPP ${CMAKE_BINARY_DIR}/header_check/${libname}.cpp)
file(WRITE ${DUMMYCPP} "#include <${hpp}> // IWYU pragma: keep\n")
file(WRITE ${DUMMYCPP} "#define OSMIUM_UTIL_COMPATIBILITY_HPP\n#define OSMIUM_DEPRECATED\n#include <${hpp}> // IWYU pragma: keep\n")
# There is no way in CMake to just compile but not link a C++ file,
# so we pretend to build a library here.
@ -416,7 +424,7 @@ endif()
#
#-----------------------------------------------------------------------------
message(STATUS "Looking for clang-tidy")
find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-6.0 clang-tidy-5.0)
find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-10 clang-tidy-9 clang-tidy-8 clang-tidy-7 clang-tidy-7.0 clang-tidy-6.0 clang-tidy-5.0)
if(CLANG_TIDY)
message(STATUS "Looking for clang-tidy - found ${CLANG_TIDY}")
@ -459,6 +467,7 @@ if(CLANG_TIDY)
add_custom_target(clang-tidy
${CLANG_TIDY}
-p ${CMAKE_BINARY_DIR}
"-extra-arg=-Wno-#pragma-messages"
${CT_CHECK_FILES}
)
else()
@ -480,11 +489,6 @@ if(INSTALL_GDALCPP)
install(FILES include/gdalcpp.hpp DESTINATION include)
endif()
if(INSTALL_UTFCPP)
install(FILES include/utf8.h DESTINATION include)
install(DIRECTORY include/utf8 DESTINATION include)
endif()
#-----------------------------------------------------------------------------
#

View File

@ -1,27 +0,0 @@
==== For utf8.h
Copyright 2006 Nemanja Trifunovic
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.

View File

@ -1,17 +1,17 @@
# Libosmium
http://osmcode.org/libosmium
https://osmcode.org/libosmium
A fast and flexible C++ library for working with OpenStreetMap data.
Libosmium works on Linux, Mac OSX and Windows.
[![Travis Build Status](https://secure.travis-ci.org/osmcode/libosmium.svg)](https://travis-ci.org/osmcode/libosmium)
[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/github/osmcode/libosmium?svg=true)](https://ci.appveyor.com/project/Mapbox/libosmium)
[![Appveyor Build status](https://ci.appveyor.com/api/projects/status/yy099a4vxcb604rn/branch/master?svg=true)](https://ci.appveyor.com/project/lonvia/libosmium-eq41p/branch/master)
[![Coverage Status](https://codecov.io/gh/osmcode/libosmium/branch/master/graph/badge.svg)](https://codecov.io/gh/osmcode/libosmium)
[![Packaging status](https://repology.org/badge/tiny-repos/libosmium.svg)](https://repology.org/metapackage/libosmium)
Please see the [Libosmium manual](http://osmcode.org/libosmium/manual.html)
Please see the [Libosmium manual](https://osmcode.org/libosmium/manual.html)
for more details than this README can provide.
@ -26,13 +26,12 @@ different libraries. You DO NOT NEED to install all of them, just install those
you need for your programs.
For details see the [list of
dependencies](http://osmcode.org/libosmium/manual.html#dependencies) in the
dependencies](https://osmcode.org/libosmium/manual.html#dependencies) in the
manual.
The following external (header-only) libraries are included in the libosmium
repository:
* [gdalcpp](https://github.com/joto/gdalcpp)
* [utfcpp](http://utfcpp.sourceforge.net/)
Note that [protozero](https://github.com/mapbox/protozero) was included in
earlier versions of libosmium, but isn't any more.
@ -69,8 +68,8 @@ cmake:
This will build the examples and tests. Call `ctest` to run the tests.
For more detals see the
[Building Libosmium](http://osmcode.org/libosmium/manual.html#building-libosmium)
For more details see the
[Building Libosmium](https://osmcode.org/libosmium/manual.html#building-libosmium)
chapter in the manual.
@ -85,7 +84,7 @@ git submodule update --init
This will enable additional tests.
See the
[Libosmium Manual](http://osmcode.org/libosmium/manual.html#running-tests)
[Libosmium Manual](https://osmcode.org/libosmium/manual.html#running-tests)
for instructions.
@ -93,7 +92,7 @@ for instructions.
If you have been using the old version of Osmium at
https://github.com/joto/osmium you might want to read about the [changes
needed](http://osmcode.org/libosmium/manual.html#changes-from-old-versions-of-osmium).
needed](https://osmcode.org/libosmium/manual.html#changes-from-old-versions-of-osmium).
## License

View File

@ -4,25 +4,28 @@
#
#-----------------------------------------------------------------------------
environment:
matrix:
- config: MSYS2
autocrlf: true
- config: Debug
autocrlf: true
- config: Release
autocrlf: true
- config: Debug
autocrlf: false
- config: Release
autocrlf: false
os: Visual Studio 2017
platform: x64
clone_depth: 1
# Operating system (build VM template)
os: Visual Studio 2015
#-----------------------------------------------------------------------------
platform: x64
environment:
matrix:
- config: Debug
autocrlf: true
- config: Release
autocrlf: true
- config: Debug
autocrlf: false
- config: Release
autocrlf: false
- config: MSYS2
autocrlf: true
#-----------------------------------------------------------------------------
# scripts that are called at very beginning, before repo cloning
init:

View File

@ -39,16 +39,21 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
const std::string input_filename{argv[1]};
try {
const std::string input_filename{argv[1]};
osmium::io::Reader reader{input_filename};
osmium::io::Reader reader{input_filename};
CountHandler handler;
osmium::apply(reader, handler);
reader.close();
CountHandler handler;
osmium::apply(reader, handler);
reader.close();
std::cout << "Nodes: " << handler.nodes << '\n';
std::cout << "Ways: " << handler.ways << '\n';
std::cout << "Relations: " << handler.relations << '\n';
std::cout << "Nodes: " << handler.nodes << '\n';
std::cout << "Ways: " << handler.ways << '\n';
std::cout << "Relations: " << handler.relations << '\n';
} catch (const std::exception& e) {
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -42,14 +42,19 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
const std::string input_filename{argv[1]};
try {
const std::string input_filename{argv[1]};
osmium::io::Reader reader{input_filename};
osmium::io::Reader reader{input_filename};
CountHandler handler;
osmium::apply(reader, handler);
reader.close();
CountHandler handler;
osmium::apply(reader, handler);
reader.close();
std::cout << "r_all=" << handler.all << " r_counter=" << handler.counter << '\n';
std::cout << "r_all=" << handler.all << " r_counter=" << handler.counter << '\n';
} catch (const std::exception& e) {
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -24,17 +24,22 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
const std::string input_filename{argv[1]};
const std::string location_store{argv[2]};
try {
const std::string input_filename{argv[1]};
const std::string location_store{argv[2]};
osmium::io::Reader reader{input_filename};
osmium::io::Reader reader{input_filename};
const auto& map_factory = osmium::index::MapFactory<osmium::unsigned_object_id_type, osmium::Location>::instance();
std::unique_ptr<index_type> index = map_factory.create_map(location_store);
location_handler_type location_handler{*index};
location_handler.ignore_errors();
const auto& map_factory = osmium::index::MapFactory<osmium::unsigned_object_id_type, osmium::Location>::instance();
std::unique_ptr<index_type> index = map_factory.create_map(location_store);
location_handler_type location_handler{*index};
location_handler.ignore_errors();
osmium::apply(reader, location_handler);
reader.close();
osmium::apply(reader, location_handler);
reader.close();
} catch (const std::exception& e) {
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -31,12 +31,17 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
const std::string input_filename{argv[1]};
try {
const std::string input_filename{argv[1]};
osmium::io::Reader reader{input_filename};
osmium::io::Reader reader{input_filename};
GeomHandler handler;
osmium::apply(reader, handler);
reader.close();
GeomHandler handler;
osmium::apply(reader, handler);
reader.close();
} catch (const std::exception& e) {
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -44,101 +44,106 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
const std::string input_filename{argv[1]};
try {
const std::string input_filename{argv[1]};
osmium::memory::Buffer buffer{osmium::io::read_file(input_filename)};
osmium::memory::Buffer buffer{osmium::io::read_file(input_filename)};
const auto& map_factory = osmium::index::MapFactory<osmium::unsigned_object_id_type, osmium::Location>::instance();
const auto& map_factory = osmium::index::MapFactory<osmium::unsigned_object_id_type, osmium::Location>::instance();
const auto buffer_size = buffer.committed() / (1024 * 1024); // buffer size in MBytes
const int runs = std::max(10, static_cast<int>(5000ull / buffer_size));
const auto buffer_size = buffer.committed() / (1024 * 1024); // buffer size in MBytes
const int runs = std::max(10, static_cast<int>(5000ULL / buffer_size));
std::cout << "input: filename=" << input_filename << " buffer_size=" << buffer_size << "MBytes\n";
std::cout << "runs: " << runs << "\n";
std::cout << "input: filename=" << input_filename << " buffer_size=" << buffer_size << "MBytes\n";
std::cout << "runs: " << runs << "\n";
double static_min = std::numeric_limits<double>::max();
double static_sum = 0;
double static_max = 0;
double static_min = std::numeric_limits<double>::max();
double static_sum = 0;
double static_max = 0;
double dynamic_min = std::numeric_limits<double>::max();
double dynamic_sum = 0;
double dynamic_max = 0;
double dynamic_min = std::numeric_limits<double>::max();
double dynamic_sum = 0;
double dynamic_max = 0;
for (int i = 0; i < runs; ++i) {
for (int i = 0; i < runs; ++i) {
{
// static index
osmium::memory::Buffer tmp_buffer{buffer.committed()};
for (const auto& item : buffer) {
tmp_buffer.add_item(item);
tmp_buffer.commit();
{
// static index
osmium::memory::Buffer tmp_buffer{buffer.committed()};
for (const auto& item : buffer) {
tmp_buffer.add_item(item);
tmp_buffer.commit();
}
static_index_type static_index;
static_location_handler_type static_location_handler{static_index};
const auto start = std::chrono::steady_clock::now();
osmium::apply(tmp_buffer, static_location_handler);
const auto end = std::chrono::steady_clock::now();
const double duration = std::chrono::duration<double, std::milli>(end - start).count();
if (duration < static_min) {
static_min = duration;
}
if (duration > static_max) {
static_max = duration;
}
static_sum += duration;
}
static_index_type static_index;
static_location_handler_type static_location_handler{static_index};
{
// dynamic index
osmium::memory::Buffer tmp_buffer{buffer.committed()};
for (const auto& item : buffer) {
tmp_buffer.add_item(item);
tmp_buffer.commit();
}
const auto start = std::chrono::steady_clock::now();
osmium::apply(tmp_buffer, static_location_handler);
const auto end = std::chrono::steady_clock::now();
std::unique_ptr<dynamic_index_type> index = map_factory.create_map(location_store);
dynamic_location_handler_type dynamic_location_handler{*index};
dynamic_location_handler.ignore_errors();
const double duration = std::chrono::duration<double, std::milli>(end - start).count();
const auto start = std::chrono::steady_clock::now();
osmium::apply(tmp_buffer, dynamic_location_handler);
const auto end = std::chrono::steady_clock::now();
if (duration < static_min) {
static_min = duration;
const double duration = std::chrono::duration<double, std::milli>(end - start).count();
if (duration < dynamic_min) {
dynamic_min = duration;
}
if (duration > dynamic_max) {
dynamic_max = duration;
}
dynamic_sum += duration;
}
if (duration > static_max) {
static_max = duration;
}
static_sum += duration;
}
{
// dynamic index
osmium::memory::Buffer tmp_buffer{buffer.committed()};
for (const auto& item : buffer) {
tmp_buffer.add_item(item);
tmp_buffer.commit();
}
const double static_avg = static_sum / runs;
const double dynamic_avg = dynamic_sum / runs;
std::unique_ptr<dynamic_index_type> index = map_factory.create_map(location_store);
dynamic_location_handler_type dynamic_location_handler{*index};
dynamic_location_handler.ignore_errors();
std::cout << "static min=" << static_min << "ms avg=" << static_avg << "ms max=" << static_max << "ms\n";
std::cout << "dynamic min=" << dynamic_min << "ms avg=" << dynamic_avg << "ms max=" << dynamic_max << "ms\n";
const auto start = std::chrono::steady_clock::now();
osmium::apply(tmp_buffer, dynamic_location_handler);
const auto end = std::chrono::steady_clock::now();
const double rfactor = 100.0;
const double diff_min = std::round((dynamic_min - static_min) * rfactor) / rfactor;
const double diff_avg = std::round((dynamic_avg - static_avg) * rfactor) / rfactor;
const double diff_max = std::round((dynamic_max - static_max) * rfactor) / rfactor;
const double duration = std::chrono::duration<double, std::milli>(end - start).count();
const double prfactor = 10.0;
const double percent_min = std::round((100.0 * diff_min / static_min) * prfactor) / prfactor;
const double percent_avg = std::round((100.0 * diff_avg / static_avg) * prfactor) / prfactor;
const double percent_max = std::round((100.0 * diff_max / static_max) * prfactor) / prfactor;
if (duration < dynamic_min) {
dynamic_min = duration;
}
if (duration > dynamic_max) {
dynamic_max = duration;
}
dynamic_sum += duration;
}
std::cout << "difference:";
std::cout << " min=" << diff_min << "ms (" << percent_min << "%)";
std::cout << " avg=" << diff_avg << "ms (" << percent_avg << "%)";
std::cout << " max=" << diff_max << "ms (" << percent_max << "%)\n";
} catch (const std::exception& e) {
std::cerr << e.what() << '\n';
std::exit(1);
}
const double static_avg = static_sum / runs;
const double dynamic_avg = dynamic_sum / runs;
std::cout << "static min=" << static_min << "ms avg=" << static_avg << "ms max=" << static_max << "ms\n";
std::cout << "dynamic min=" << dynamic_min << "ms avg=" << dynamic_avg << "ms max=" << dynamic_max << "ms\n";
const double rfactor = 100.0;
const double diff_min = std::round((dynamic_min - static_min) * rfactor) / rfactor;
const double diff_avg = std::round((dynamic_avg - static_avg) * rfactor) / rfactor;
const double diff_max = std::round((dynamic_max - static_max) * rfactor) / rfactor;
const double prfactor = 10.0;
const double percent_min = std::round((100.0 * diff_min / static_min) * prfactor) / prfactor;
const double percent_avg = std::round((100.0 * diff_avg / static_avg) * prfactor) / prfactor;
const double percent_max = std::round((100.0 * diff_max / static_max) * prfactor) / prfactor;
std::cout << "difference:";
std::cout << " min=" << diff_min << "ms (" << percent_min << "%)";
std::cout << " avg=" << diff_avg << "ms (" << percent_avg << "%)";
std::cout << " max=" << diff_max << "ms (" << percent_max << "%)\n";
}

View File

@ -17,19 +17,24 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
std::string input_filename{argv[1]};
std::string output_filename{argv[2]};
try {
std::string input_filename{argv[1]};
std::string output_filename{argv[2]};
osmium::io::Reader reader{input_filename};
osmium::io::File output_file{output_filename, "pbf"};
osmium::io::Header header;
osmium::io::Writer writer{output_file, header, osmium::io::overwrite::allow};
osmium::io::Reader reader{input_filename};
osmium::io::File output_file{output_filename, "pbf"};
osmium::io::Header header;
osmium::io::Writer writer{output_file, header, osmium::io::overwrite::allow};
while (osmium::memory::Buffer buffer = reader.read()) {
writer(std::move(buffer));
while (osmium::memory::Buffer buffer = reader.read()) { // NOLINT(bugprone-use-after-move) Bug in clang-tidy https://bugs.llvm.org/show_bug.cgi?id=36516
writer(std::move(buffer));
}
writer.close();
reader.close();
} catch (const std::exception& e) {
std::cerr << e.what() << '\n';
std::exit(1);
}
writer.close();
reader.close();
}

View File

@ -46,7 +46,7 @@ SET CMAKE_CMD=cmake .. -LA -G "Visual Studio 14 Win64" ^
-DOsmium_DEBUG=TRUE ^
-DCMAKE_BUILD_TYPE=%config% ^
-DBUILD_HEADERS=OFF ^
-DBOOST_ROOT=C:/Libraries/boost_1_63_0 ^
-DBOOST_ROOT=C:/Libraries/boost_1_67_0 ^
-DZLIB_INCLUDE_DIR=C:/projects/zlib-vc140-static-64.1.2.11/lib/native/include ^
-DZLIB_LIBRARY=C:/projects/zlib-vc140-static-64.1.2.11/lib/native/libs/x64/static/%config%/zlibstatic.lib ^
-DEXPAT_INCLUDE_DIR=C:/projects/expat.v140.2.2.5/build/native/include ^
@ -68,7 +68,7 @@ msbuild libosmium.sln ^
/p:PlatformToolset=v140 %avlogger%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ctest --output-on-failure -C %config% -E testdata-overview
ctest --output-on-failure -C %config%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
GOTO DONE

View File

@ -13,6 +13,9 @@ bash -lc "pacman -S --needed --noconfirm mingw-w64-x86_64-gcc mingw-w64-x86_64-g
bash -lc "pacman -S --needed --noconfirm mingw-w64-x86_64-postgresql mingw-w64-x86_64-netcdf mingw-w64-x86_64-crypto++"
call C:\msys64\mingw64\bin\gem.cmd install json
REM Workaround for problem with spatialite (see https://github.com/osmcode/libosmium/issues/262)
copy /y C:\msys64\mingw64\bin\libreadline8.dll C:\msys64\mingw64\bin\libreadline7.dll
echo "Setting PROJ_LIB variable for correct PROJ.4 working"
set PROJ_LIB=c:\msys64\mingw64\share\proj

View File

@ -71,6 +71,9 @@ find_path(OSMIUM_INCLUDE_DIR osmium/version.hpp
# Check libosmium version number
if(Osmium_FIND_VERSION)
if(NOT EXISTS "${OSMIUM_INCLUDE_DIR}/osmium/version.hpp")
message(FATAL_ERROR "Missing ${OSMIUM_INCLUDE_DIR}/osmium/version.hpp. Either your libosmium version is too old, or libosmium wasn't found in the place you said.")
endif()
file(STRINGS "${OSMIUM_INCLUDE_DIR}/osmium/version.hpp" _libosmium_version_define REGEX "#define LIBOSMIUM_VERSION_STRING")
if("${_libosmium_version_define}" MATCHES "#define LIBOSMIUM_VERSION_STRING \"([0-9.]+)\"")
set(_libosmium_version "${CMAKE_MATCH_1}")
@ -111,7 +114,7 @@ endif()
if(Osmium_USE_PBF)
find_package(ZLIB)
find_package(Threads)
find_package(Protozero 1.5.1)
find_package(Protozero 1.6.3)
list(APPEND OSMIUM_EXTRA_FIND_VARS ZLIB_FOUND Threads_FOUND PROTOZERO_INCLUDE_DIR)
if(ZLIB_FOUND AND Threads_FOUND AND PROTOZERO_FOUND)
@ -324,7 +327,7 @@ if(MSVC)
add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_WARNINGS)
endif()
if(APPLE)
if(APPLE AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# following only available from cmake 2.8.12:
# add_compile_options(-stdlib=libc++)
# so using this instead:

View File

@ -4,7 +4,7 @@ data.
This is the API documentation that was automatically created from the
source code. For more information about the Osmium Library see
http://osmcode.org/libosmium .
https://osmcode.org/libosmium .
Osmium is free software and available under the Boost Software License.
The source code is available at https://github.com/osmcode/libosmium .

View File

@ -58,12 +58,12 @@ using location_handler_type = osmium::handler::NodeLocationsForWays<index_type>;
class AmenityHandler : public osmium::handler::Handler {
// Print info about one amenity to stdout.
void print_amenity(const char* type, const char* name, const osmium::geom::Coordinates& c) {
static void print_amenity(const char* type, const char* name, const osmium::geom::Coordinates& c) {
std::printf("%8.4f,%8.4f %-15s %s\n", c.x, c.y, type, name ? name : "");
}
// Calculate the center point of a NodeRefList.
osmium::geom::Coordinates calc_center(const osmium::NodeRefList& nr_list) {
static osmium::geom::Coordinates calc_center(const osmium::NodeRefList& nr_list) {
// Coordinates simply store an X and Y coordinate pair as doubles.
// (Unlike osmium::Location which stores them more efficiently as
// 32 bit integers.) Use Coordinates when you want to do calculations
@ -113,59 +113,65 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
// The input file
const osmium::io::File input_file{argv[1]};
try {
// The input file
const osmium::io::File input_file{argv[1]};
// Configuration for the multipolygon assembler. We disable the option to
// create empty areas when invalid multipolygons are encountered. This
// means areas created have a valid geometry and invalid multipolygons
// are simply ignored.
osmium::area::Assembler::config_type assembler_config;
assembler_config.create_empty_areas = false;
// Configuration for the multipolygon assembler. We disable the option to
// create empty areas when invalid multipolygons are encountered. This
// means areas created have a valid geometry and invalid multipolygons
// are simply ignored.
osmium::area::Assembler::config_type assembler_config;
assembler_config.create_empty_areas = false;
// Initialize the MultipolygonManager. Its job is to collect all
// relations and member ways needed for each area. It then calls an
// instance of the osmium::area::Assembler class (with the given config)
// to actually assemble one area.
osmium::area::MultipolygonManager<osmium::area::Assembler> mp_manager{assembler_config};
// Initialize the MultipolygonManager. Its job is to collect all
// relations and member ways needed for each area. It then calls an
// instance of the osmium::area::Assembler class (with the given config)
// to actually assemble one area.
osmium::area::MultipolygonManager<osmium::area::Assembler> mp_manager{assembler_config};
// We read the input file twice. In the first pass, only relations are
// read and fed into the multipolygon manager.
std::cerr << "Pass 1...\n";
osmium::relations::read_relations(input_file, mp_manager);
std::cerr << "Pass 1 done\n";
// We read the input file twice. In the first pass, only relations are
// read and fed into the multipolygon manager.
std::cerr << "Pass 1...\n";
osmium::relations::read_relations(input_file, mp_manager);
std::cerr << "Pass 1 done\n";
// The index storing all node locations.
index_type index;
// The index storing all node locations.
index_type index;
// The handler that stores all node locations in the index and adds them
// to the ways.
location_handler_type location_handler{index};
// The handler that stores all node locations in the index and adds them
// to the ways.
location_handler_type location_handler{index};
// If a location is not available in the index, we ignore it. It might
// not be needed (if it is not part of a multipolygon relation), so why
// create an error?
location_handler.ignore_errors();
// If a location is not available in the index, we ignore it. It might
// not be needed (if it is not part of a multipolygon relation), so why
// create an error?
location_handler.ignore_errors();
// Create our handler.
AmenityHandler data_handler;
// Create our handler.
AmenityHandler data_handler;
// On the second pass we read all objects and run them first through the
// node location handler and then the multipolygon manager. The manager
// will put the areas it has created into the "buffer" which are then
// fed through our handler.
//
// The read_meta::no option disables reading of meta data (such as version
// numbers, timestamps, etc.) which are not needed in this case. Disabling
// this can speed up your program.
std::cerr << "Pass 2...\n";
osmium::io::Reader reader{input_file, osmium::io::read_meta::no};
// On the second pass we read all objects and run them first through the
// node location handler and then the multipolygon manager. The manager
// will put the areas it has created into the "buffer" which are then
// fed through our handler.
//
// The read_meta::no option disables reading of meta data (such as version
// numbers, timestamps, etc.) which are not needed in this case. Disabling
// this can speed up your program.
std::cerr << "Pass 2...\n";
osmium::io::Reader reader{input_file, osmium::io::read_meta::no};
osmium::apply(reader, location_handler, data_handler, mp_manager.handler([&data_handler](const osmium::memory::Buffer& area_buffer) {
osmium::apply(area_buffer, data_handler);
}));
osmium::apply(reader, location_handler, data_handler, mp_manager.handler([&data_handler](const osmium::memory::Buffer& area_buffer) {
osmium::apply(area_buffer, data_handler);
}));
reader.close();
std::cerr << "Pass 2 done\n";
reader.close();
std::cerr << "Pass 2 done\n";
} catch (const std::exception& e) {
// All exceptions used by the Osmium library derive from std::exception.
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -107,92 +107,98 @@ int main(int argc, char* argv[]) {
print_usage(argv[0]);
}
// Initialize an empty DynamicHandler. Later it will be associated
// with one of the handlers. You can think of the DynamicHandler as
// a kind of "variant handler" or a "pointer handler" pointing to the
// real handler.
osmium::handler::DynamicHandler handler;
try {
// Initialize an empty DynamicHandler. Later it will be associated
// with one of the handlers. You can think of the DynamicHandler as
// a kind of "variant handler" or a "pointer handler" pointing to the
// real handler.
osmium::handler::DynamicHandler handler;
if (!std::strcmp(argv[1], "-w") || !std::strcmp(argv[1], "--dump-wkt")) {
handler.set<WKTDump>();
} else if (!std::strcmp(argv[1], "-o") || !std::strcmp(argv[1], "--dump-objects")) {
handler.set<osmium::handler::Dump>(std::cout);
} else {
print_usage(argv[0]);
}
osmium::io::File input_file{argv[2]};
// Configuration for the multipolygon assembler. Here the default settings
// are used, but you could change multiple settings.
osmium::area::Assembler::config_type assembler_config;
// Set up a filter matching only forests. This will be used to only build
// areas with matching tags.
osmium::TagsFilter filter{false};
filter.add_rule(true, "landuse", "forest");
filter.add_rule(true, "natural", "wood");
// Initialize the MultipolygonManager. Its job is to collect all
// relations and member ways needed for each area. It then calls an
// instance of the osmium::area::Assembler class (with the given config)
// to actually assemble one area. The filter parameter is optional, if
// it is not set, all areas will be built.
osmium::area::MultipolygonManager<osmium::area::Assembler> mp_manager{assembler_config, filter};
// We read the input file twice. In the first pass, only relations are
// read and fed into the multipolygon manager.
std::cerr << "Pass 1...\n";
osmium::relations::read_relations(input_file, mp_manager);
std::cerr << "Pass 1 done\n";
// Output the amount of main memory used so far. All multipolygon relations
// are in memory now.
std::cerr << "Memory:\n";
osmium::relations::print_used_memory(std::cerr, mp_manager.used_memory());
// The index storing all node locations.
index_type index;
// The handler that stores all node locations in the index and adds them
// to the ways.
location_handler_type location_handler{index};
// If a location is not available in the index, we ignore it. It might
// not be needed (if it is not part of a multipolygon relation), so why
// create an error?
location_handler.ignore_errors();
// On the second pass we read all objects and run them first through the
// node location handler and then the multipolygon collector. The collector
// will put the areas it has created into the "buffer" which are then
// fed through our "handler".
std::cerr << "Pass 2...\n";
osmium::io::Reader reader{input_file};
osmium::apply(reader, location_handler, mp_manager.handler([&handler](osmium::memory::Buffer&& buffer) {
osmium::apply(buffer, handler);
}));
reader.close();
std::cerr << "Pass 2 done\n";
// Output the amount of main memory used so far. All complete multipolygon
// relations have been cleaned up.
std::cerr << "Memory:\n";
osmium::relations::print_used_memory(std::cerr, mp_manager.used_memory());
// If there were multipolgyon relations in the input, but some of their
// members are not in the input file (which often happens for extracts)
// this will write the IDs of the incomplete relations to stderr.
std::vector<osmium::object_id_type> incomplete_relations_ids;
mp_manager.for_each_incomplete_relation([&](const osmium::relations::RelationHandle& handle){
incomplete_relations_ids.push_back(handle->id());
});
if (!incomplete_relations_ids.empty()) {
std::cerr << "Warning! Some member ways missing for these multipolygon relations:";
for (const auto id : incomplete_relations_ids) {
std::cerr << " " << id;
if (!std::strcmp(argv[1], "-w") || !std::strcmp(argv[1], "--dump-wkt")) {
handler.set<WKTDump>();
} else if (!std::strcmp(argv[1], "-o") || !std::strcmp(argv[1], "--dump-objects")) {
handler.set<osmium::handler::Dump>(std::cout);
} else {
print_usage(argv[0]);
}
std::cerr << "\n";
osmium::io::File input_file{argv[2]};
// Configuration for the multipolygon assembler. Here the default settings
// are used, but you could change multiple settings.
osmium::area::Assembler::config_type assembler_config;
// Set up a filter matching only forests. This will be used to only build
// areas with matching tags.
osmium::TagsFilter filter{false};
filter.add_rule(true, "landuse", "forest");
filter.add_rule(true, "natural", "wood");
// Initialize the MultipolygonManager. Its job is to collect all
// relations and member ways needed for each area. It then calls an
// instance of the osmium::area::Assembler class (with the given config)
// to actually assemble one area. The filter parameter is optional, if
// it is not set, all areas will be built.
osmium::area::MultipolygonManager<osmium::area::Assembler> mp_manager{assembler_config, filter};
// We read the input file twice. In the first pass, only relations are
// read and fed into the multipolygon manager.
std::cerr << "Pass 1...\n";
osmium::relations::read_relations(input_file, mp_manager);
std::cerr << "Pass 1 done\n";
// Output the amount of main memory used so far. All multipolygon relations
// are in memory now.
std::cerr << "Memory:\n";
osmium::relations::print_used_memory(std::cerr, mp_manager.used_memory());
// The index storing all node locations.
index_type index;
// The handler that stores all node locations in the index and adds them
// to the ways.
location_handler_type location_handler{index};
// If a location is not available in the index, we ignore it. It might
// not be needed (if it is not part of a multipolygon relation), so why
// create an error?
location_handler.ignore_errors();
// On the second pass we read all objects and run them first through the
// node location handler and then the multipolygon collector. The collector
// will put the areas it has created into the "buffer" which are then
// fed through our "handler".
std::cerr << "Pass 2...\n";
osmium::io::Reader reader{input_file};
osmium::apply(reader, location_handler, mp_manager.handler([&handler](osmium::memory::Buffer&& buffer) {
osmium::apply(buffer, handler);
}));
reader.close();
std::cerr << "Pass 2 done\n";
// Output the amount of main memory used so far. All complete multipolygon
// relations have been cleaned up.
std::cerr << "Memory:\n";
osmium::relations::print_used_memory(std::cerr, mp_manager.used_memory());
// If there were multipolgyon relations in the input, but some of their
// members are not in the input file (which often happens for extracts)
// this will write the IDs of the incomplete relations to stderr.
std::vector<osmium::object_id_type> incomplete_relations_ids;
mp_manager.for_each_incomplete_relation([&](const osmium::relations::RelationHandle& handle){
incomplete_relations_ids.push_back(handle->id());
});
if (!incomplete_relations_ids.empty()) {
std::cerr << "Warning! Some member ways missing for these multipolygon relations:";
for (const auto id : incomplete_relations_ids) {
std::cerr << " " << id;
}
std::cerr << "\n";
}
} catch (const std::exception& e) {
// All exceptions used by the Osmium library derive from std::exception.
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -66,7 +66,7 @@ class RewriteHandler : public osmium::handler::Handler {
// 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) {
static 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
@ -196,7 +196,7 @@ int main(int argc, char* argv[]) {
reader.close();
} catch (const std::exception& e) {
// All exceptions used by the Osmium library derive from std::exception.
std::cerr << e.what() << "\n";
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -135,7 +135,7 @@ int main(int argc, char* argv[]) {
// a time. This is much easier and faster than copying each object
// in the file. Buffers are moved around, so there is no cost for
// copying in memory.
while (osmium::memory::Buffer buffer = reader.read()) {
while (osmium::memory::Buffer buffer = reader.read()) { // NOLINT(bugprone-use-after-move) Bug in clang-tidy https://bugs.llvm.org/show_bug.cgi?id=36516
writer(std::move(buffer));
}
@ -147,7 +147,7 @@ int main(int argc, char* argv[]) {
reader.close();
} catch (const std::exception& e) {
// All exceptions used by the Osmium library derive from std::exception.
std::cerr << e.what() << "\n";
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -66,30 +66,36 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
// The Reader is initialized here with an osmium::io::File, but could
// also be directly initialized with a file name.
osmium::io::File input_file{argv[1]};
osmium::io::Reader reader{input_file};
try {
// The Reader is initialized here with an osmium::io::File, but could
// also be directly initialized with a file name.
osmium::io::File input_file{argv[1]};
osmium::io::Reader reader{input_file};
// Create an instance of our own CountHandler and push the data from the
// input file through it.
CountHandler handler;
osmium::apply(reader, handler);
// Create an instance of our own CountHandler and push the data from the
// input file through it.
CountHandler handler;
osmium::apply(reader, handler);
// You do not have to close the Reader explicitly, but because the
// destructor can't throw, you will not see any errors otherwise.
reader.close();
// You do not have to close the Reader explicitly, but because the
// destructor can't throw, you will not see any errors otherwise.
reader.close();
std::cout << "Nodes: " << handler.nodes << "\n";
std::cout << "Ways: " << handler.ways << "\n";
std::cout << "Relations: " << handler.relations << "\n";
std::cout << "Nodes: " << handler.nodes << "\n";
std::cout << "Ways: " << handler.ways << "\n";
std::cout << "Relations: " << handler.relations << "\n";
// Because of the huge amount of OSM data, some Osmium-based programs
// (though not this one) can use huge amounts of data. So checking actual
// memore usage is often useful and can be done easily with this class.
// (Currently only works on Linux, not OSX and Windows.)
osmium::MemoryUsage memory;
// Because of the huge amount of OSM data, some Osmium-based programs
// (though not this one) can use huge amounts of data. So checking actual
// memore usage is often useful and can be done easily with this class.
// (Currently only works on Linux, not OSX and Windows.)
osmium::MemoryUsage memory;
std::cout << "\nMemory used: " << memory.peak() << " MBytes\n";
std::cout << "\nMemory used: " << memory.peak() << " MBytes\n";
} catch (const std::exception& e) {
// All exceptions used by the Osmium library derive from std::exception.
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -93,7 +93,7 @@ int main(int argc, char* argv[]) {
writer.close();
} catch (const std::exception& e) {
// All exceptions used by the Osmium library derive from std::exception.
std::cerr << e.what() << "\n";
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -37,48 +37,54 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
// Default is all entity types: nodes, ways, relations, and changesets
osmium::osm_entity_bits::type read_types = osmium::osm_entity_bits::all;
try {
// Default is all entity types: nodes, ways, relations, and changesets
osmium::osm_entity_bits::type read_types = osmium::osm_entity_bits::all;
// Get entity types from command line if there is a 2nd argument.
if (argc == 3) {
read_types = osmium::osm_entity_bits::nothing;
std::string types = argv[2];
if (types.find('n') != std::string::npos) {
read_types |= osmium::osm_entity_bits::node;
// Get entity types from command line if there is a 2nd argument.
if (argc == 3) {
read_types = osmium::osm_entity_bits::nothing;
std::string types = argv[2];
if (types.find('n') != std::string::npos) {
read_types |= osmium::osm_entity_bits::node;
}
if (types.find('w') != std::string::npos) {
read_types |= osmium::osm_entity_bits::way;
}
if (types.find('r') != std::string::npos) {
read_types |= osmium::osm_entity_bits::relation;
}
if (types.find('c') != std::string::npos) {
read_types |= osmium::osm_entity_bits::changeset;
}
}
if (types.find('w') != std::string::npos) {
read_types |= osmium::osm_entity_bits::way;
}
if (types.find('r') != std::string::npos) {
read_types |= osmium::osm_entity_bits::relation;
}
if (types.find('c') != std::string::npos) {
read_types |= osmium::osm_entity_bits::changeset;
// Initialize Reader with file name and the types of entities we want to
// read.
osmium::io::Reader reader{argv[1], read_types};
// The file header can contain metadata such as the program that generated
// the file and the bounding box of the data.
osmium::io::Header header = reader.header();
std::cout << "HEADER:\n generator=" << header.get("generator") << "\n";
for (const auto& bbox : header.boxes()) {
std::cout << " bbox=" << bbox << "\n";
}
// Initialize Dump handler.
osmium::handler::Dump dump{std::cout};
// Read from input and send everything to Dump handler.
osmium::apply(reader, dump);
// You do not have to close the Reader explicitly, but because the
// destructor can't throw, you will not see any errors otherwise.
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);
}
// Initialize Reader with file name and the types of entities we want to
// read.
osmium::io::Reader reader{argv[1], read_types};
// The file header can contain metadata such as the program that generated
// the file and the bounding box of the data.
osmium::io::Header header = reader.header();
std::cout << "HEADER:\n generator=" << header.get("generator") << "\n";
for (const auto& bbox : header.boxes()) {
std::cout << " bbox=" << bbox << "\n";
}
// Initialize Dump handler.
osmium::handler::Dump dump{std::cout};
// Read from input and send everything to Dump handler.
osmium::apply(reader, dump);
// You do not have to close the Reader explicitly, but because the
// destructor can't throw, you will not see any errors otherwise.
reader.close();
}

View File

@ -105,92 +105,98 @@ int main(int argc, char* argv[]) {
std::exit(2);
}
const std::string input_file_name{argv[1]};
const std::string output_dir{argv[2]};
try {
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.
// Create output directory. Ignore the error if it already exists.
#ifndef _WIN32
const int result = ::mkdir(output_dir.c_str(), 0777);
const int result = ::mkdir(output_dir.c_str(), 0777);
#else
const int result = mkdir(output_dir.c_str());
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);
}
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); // NOLINT(hicpp-signed-bitwise)
if (data_fd < 0) {
std::cerr << "Can't open data file '" << data_file << "': " << 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); // NOLINT(hicpp-signed-bitwise)
if (data_fd < 0) {
std::cerr << "Can't open data file '" << data_file << "': " << std::strerror(errno) << "\n";
std::exit(2);
}
#ifdef _WIN32
_setmode(data_fd, _O_BINARY);
_setmode(data_fd, _O_BINARY);
#endif
// 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;
// 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};
// 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;
// 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};
// 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};
// 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);
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);
// 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());
} catch (const std::exception& e) {
// All exceptions used by the Osmium library derive from std::exception.
std::cerr << e.what() << '\n';
std::exit(1);
}
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());
}

View File

@ -46,47 +46,53 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
// The input file, deduce file format from file suffix.
osmium::io::File input_file{argv[1]};
try {
// The input file, deduce file format from file suffix.
osmium::io::File input_file{argv[1]};
// The output file, force XML OSM file format.
osmium::io::File output_file{argv[2], "osm"};
// The output file, force XML OSM file format.
osmium::io::File output_file{argv[2], "osm"};
// Initialize Reader for the input file.
// Read only changesets (will ignore nodes, ways, and
// relations if there are any).
osmium::io::Reader reader{input_file, osmium::osm_entity_bits::changeset};
// Initialize Reader for the input file.
// Read only changesets (will ignore nodes, ways, and
// relations if there are any).
osmium::io::Reader reader{input_file, osmium::osm_entity_bits::changeset};
// Get the header from the input file.
osmium::io::Header header = reader.header();
// Get the header from the input file.
osmium::io::Header header = reader.header();
// Set the "generator" on the header to ourselves.
header.set("generator", "osmium_filter_discussions");
// Set the "generator" on the header to ourselves.
header.set("generator", "osmium_filter_discussions");
// Initialize writer for the output file. Use the header from the input
// 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};
// Initialize writer for the output file. Use the header from the input
// 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};
// Create range of input iterators that will iterator over all changesets
// delivered from input file through the "reader".
auto input_range = osmium::io::make_input_iterator_range<osmium::Changeset>(reader);
// Create range of input iterators that will iterator over all changesets
// delivered from input file through the "reader".
auto input_range = osmium::io::make_input_iterator_range<osmium::Changeset>(reader);
// Create an output iterator writing through the "writer" object to the
// output file.
auto output_iterator = osmium::io::make_output_iterator(writer);
// Create an output iterator writing through the "writer" object to the
// output file.
auto output_iterator = osmium::io::make_output_iterator(writer);
// Copy all changesets from input to output that have at least one comment.
std::copy_if(input_range.begin(), input_range.end(), output_iterator, [](const osmium::Changeset& changeset) {
return changeset.num_comments() > 0;
});
// Copy all changesets from input to output that have at least one comment.
std::copy_if(input_range.begin(), input_range.end(), output_iterator, [](const osmium::Changeset& changeset) {
return changeset.num_comments() > 0;
});
// 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();
// 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);
}
}

View File

@ -182,7 +182,7 @@ class Options {
bool m_array_format = false;
bool m_list_format = false;
void print_help() {
static 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"
@ -193,7 +193,7 @@ class Options {
;
}
void print_usage(const char* prgname) {
static void print_usage(const char* prgname) {
std::cout << "Usage: " << prgname << " [OPTIONS]\n\n";
std::exit(0);
}
@ -363,7 +363,8 @@ int main(int argc, char* argv[]) {
const auto index = create<std::size_t>(options.dense_format(), fd);
return run(*index, options);
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << '\n';
// All exceptions used by the Osmium library derive from std::exception.
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -65,30 +65,36 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
const std::string input_filename{argv[1]};
const std::string cache_filename{argv[2]};
try {
const std::string input_filename{argv[1]};
const std::string cache_filename{argv[2]};
// Construct Reader reading only nodes
osmium::io::Reader reader{input_filename, osmium::osm_entity_bits::node};
// Construct Reader reading only nodes
osmium::io::Reader reader{input_filename, osmium::osm_entity_bits::node};
// Initialize location index on disk creating a new file.
const int fd = ::open(cache_filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666); // NOLINT(hicpp-signed-bitwise)
if (fd == -1) {
std::cerr << "Can not open location cache file '" << cache_filename << "': " << std::strerror(errno) << "\n";
// Initialize location index on disk creating a new file.
const int fd = ::open(cache_filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666); // NOLINT(hicpp-signed-bitwise)
if (fd == -1) {
std::cerr << "Can not open location cache file '" << cache_filename << "': " << std::strerror(errno) << "\n";
std::exit(1);
}
#ifdef _WIN32
_setmode(fd, _O_BINARY);
#endif
index_type index{fd};
// The handler that stores all node locations in the index.
location_handler_type location_handler{index};
// Feed all nodes through the location handler.
osmium::apply(reader, location_handler);
// Explicitly close input so we get notified of any errors.
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);
}
#ifdef _WIN32
_setmode(fd, _O_BINARY);
#endif
index_type index{fd};
// The handler that stores all node locations in the index.
location_handler_type location_handler{index};
// Feed all nodes through the location handler.
osmium::apply(reader, location_handler);
// Explicitly close input so we get notified of any errors.
reader.close();
}

View File

@ -78,31 +78,37 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
const std::string input_filename{argv[1]};
const std::string cache_filename{argv[2]};
try {
const std::string input_filename{argv[1]};
const std::string cache_filename{argv[2]};
// Construct Reader reading only ways
osmium::io::Reader reader{input_filename, osmium::osm_entity_bits::way};
// Construct Reader reading only ways
osmium::io::Reader reader{input_filename, osmium::osm_entity_bits::way};
// Initialize location index on disk using an existing file
const int fd = ::open(cache_filename.c_str(), O_RDWR);
if (fd == -1) {
std::cerr << "Can not open location cache file '" << cache_filename << "': " << std::strerror(errno) << "\n";
return 1;
}
// Initialize location index on disk using an existing file
const int fd = ::open(cache_filename.c_str(), O_RDWR);
if (fd == -1) {
std::cerr << "Can not open location cache file '" << cache_filename << "': " << std::strerror(errno) << "\n";
return 1;
}
#ifdef _WIN32
_setmode(fd, _O_BINARY);
_setmode(fd, _O_BINARY);
#endif
index_type index{fd};
index_type index{fd};
// The handler that adds node locations from the index to the ways.
location_handler_type location_handler{index};
// The handler that adds node locations from the index to the ways.
location_handler_type location_handler{index};
// Feed all ways through the location handler and then our own handler.
MyHandler handler;
osmium::apply(reader, location_handler, handler);
// Feed all ways through the location handler and then our own handler.
MyHandler handler;
osmium::apply(reader, location_handler, handler);
// Explicitly close input so we get notified of any errors.
reader.close();
// Explicitly close input so we get notified of any errors.
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);
}
}

View File

@ -33,7 +33,7 @@
class NamesHandler : public osmium::handler::Handler {
void output_pubs(const osmium::OSMObject& object) {
static void output_pubs(const osmium::OSMObject& object) {
const osmium::TagList& tags = object.tags();
if (tags.has_tag("amenity", "pub")) {
@ -75,15 +75,21 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
// Construct the handler defined above
NamesHandler names_handler;
try {
// Construct the handler defined above
NamesHandler names_handler;
// Initialize the reader with the filename from the command line and
// tell it to only read nodes and ways. We are ignoring multipolygon
// relations in this simple example.
osmium::io::Reader reader{argv[1], osmium::osm_entity_bits::node | osmium::osm_entity_bits::way};
// Initialize the reader with the filename from the command line and
// tell it to only read nodes and ways. We are ignoring multipolygon
// relations in this simple example.
osmium::io::Reader reader{argv[1], osmium::osm_entity_bits::node | osmium::osm_entity_bits::way};
// Apply input data to our own handler
osmium::apply(reader, names_handler);
// Apply input data to our own handler
osmium::apply(reader, names_handler);
} catch (const std::exception& e) {
// All exceptions used by the Osmium library derive from std::exception.
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -25,18 +25,24 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
// The Reader is initialized here with an osmium::io::File, but could
// also be directly initialized with a file name.
osmium::io::File input_file{argv[1]};
osmium::io::Reader reader{input_file};
try {
// The Reader is initialized here with an osmium::io::File, but could
// also be directly initialized with a file name.
osmium::io::File input_file{argv[1]};
osmium::io::Reader reader{input_file};
// OSM data comes in buffers, read until there are no more.
while (osmium::memory::Buffer buffer = reader.read()) {
// do nothing
// OSM data comes in buffers, read until there are no more.
while (osmium::memory::Buffer buffer = reader.read()) {
// do nothing
}
// You do not have to close the Reader explicitly, but because the
// destructor can't throw, you will not see any errors otherwise.
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);
}
// You do not have to close the Reader explicitly, but because the
// destructor can't throw, you will not see any errors otherwise.
reader.close();
}

View File

@ -32,25 +32,31 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
// The Reader is initialized here with an osmium::io::File, but could
// also be directly initialized with a file name.
osmium::io::File input_file{argv[1]};
osmium::io::Reader reader{input_file};
try {
// The Reader is initialized here with an osmium::io::File, but could
// also be directly initialized with a file name.
osmium::io::File input_file{argv[1]};
osmium::io::Reader reader{input_file};
// Initialize progress bar, enable it only if STDERR is a TTY.
osmium::ProgressBar progress{reader.file_size(), osmium::isatty(2)};
// Initialize progress bar, enable it only if STDERR is a TTY.
osmium::ProgressBar progress{reader.file_size(), osmium::isatty(2)};
// OSM data comes in buffers, read until there are no more.
while (osmium::memory::Buffer buffer = reader.read()) {
// Update progress bar for each buffer.
progress.update(reader.offset());
// OSM data comes in buffers, read until there are no more.
while (osmium::memory::Buffer buffer = reader.read()) {
// Update progress bar for each buffer.
progress.update(reader.offset());
}
// Progress bar is done.
progress.done();
// You do not have to close the Reader explicitly, but because the
// destructor can't throw, you will not see any errors otherwise.
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);
}
// Progress bar is done.
progress.done();
// You do not have to close the Reader explicitly, but because the
// destructor can't throw, you will not see any errors otherwise.
reader.close();
}

View File

@ -68,25 +68,31 @@ int main(int argc, char* argv[]) {
std::exit(1);
}
// Initialize the reader with the filename from the command line and
// tell it to only read nodes and ways.
osmium::io::Reader reader{argv[1], osmium::osm_entity_bits::node | osmium::osm_entity_bits::way};
try {
// Initialize the reader with the filename from the command line and
// tell it to only read nodes and ways.
osmium::io::Reader reader{argv[1], osmium::osm_entity_bits::node | osmium::osm_entity_bits::way};
// The index to hold node locations.
index_type index;
// The index to hold node locations.
index_type index;
// The location handler will add the node locations to the index and then
// to the ways
location_handler_type location_handler{index};
// The location handler will add the node locations to the index and then
// to the ways
location_handler_type location_handler{index};
// Our handler defined above
RoadLengthHandler road_length_handler;
// Our handler defined above
RoadLengthHandler road_length_handler;
// Apply input data to first the location handler and then our own handler
osmium::apply(reader, location_handler, road_length_handler);
// Apply input data to first the location handler and then our own handler
osmium::apply(reader, location_handler, road_length_handler);
// Output the length. The haversine function calculates it in meters,
// so we first devide by 1000 to get kilometers.
std::cout << "Length: " << road_length_handler.length / 1000 << " km\n";
// Output the length. The haversine function calculates it in meters,
// so we first devide by 1000 to get kilometers.
std::cout << "Length: " << road_length_handler.length / 1000 << " km\n";
} catch (const std::exception& e) {
// All exceptions used by the Osmium library derive from std::exception.
std::cerr << e.what() << '\n';
std::exit(1);
}
}

View File

@ -5,11 +5,11 @@
C++11 wrapper classes for GDAL/OGR.
Version 1.1.1
Version 1.2.0
https://github.com/joto/gdalcpp
Copyright 2015 Jochen Topf <jochen@topf.org>
Copyright 2015-2018 Jochen Topf <jochen@topf.org>
Boost Software License - Version 1.0 - August 17th, 2003
@ -37,17 +37,19 @@ DEALINGS IN THE SOFTWARE.
*/
#include <algorithm>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include <gdal_priv.h>
#include <gdal_version.h>
#include <ogr_api.h>
#include <ogrsf_frmts.h>
#include <cstdint>
#include <algorithm>
#include <memory>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
namespace gdalcpp {
#if GDAL_VERSION_MAJOR >= 2
@ -85,23 +87,23 @@ namespace gdalcpp {
m_error(error) {
}
const std::string& driver() const {
const std::string& driver() const noexcept {
return m_driver;
}
const std::string& dataset() const {
const std::string& dataset() const noexcept {
return m_dataset;
}
const std::string& layer() const {
const std::string& layer() const noexcept {
return m_layer;
}
const std::string& field() const {
const std::string& field() const noexcept {
return m_field;
}
OGRErr error() const {
OGRErr error() const noexcept {
return m_error;
}
@ -111,18 +113,26 @@ namespace gdalcpp {
struct init_wrapper {
#if GDAL_VERSION_MAJOR >= 2
init_wrapper() { GDALAllRegister(); }
init_wrapper() noexcept {
GDALAllRegister();
}
#else
init_wrapper() { OGRRegisterAll(); }
~init_wrapper() { OGRCleanupAll(); }
init_wrapper() noexcept {
OGRRegisterAll();
}
~init_wrapper() noexcept {
OGRCleanupAll();
}
#endif
};
}; // struct init_wrapper
struct init_library {
init_library() {
static init_wrapper iw;
}
};
}; // struct init_library
class Driver : private init_library {
@ -138,11 +148,13 @@ namespace gdalcpp {
m_driver(OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str())) {
#endif
if (!m_driver) {
throw gdal_error(std::string("unknown driver: '") + driver_name + "'", OGRERR_NONE, driver_name);
throw gdal_error{std::string{"unknown driver: '"} + driver_name + "'",
OGRERR_NONE,
driver_name};
}
}
gdal_driver_type& get() const {
gdal_driver_type& get() const noexcept {
return *m_driver;
}
@ -155,14 +167,14 @@ namespace gdalcpp {
Options(const std::vector<std::string>& options) :
m_options(options),
m_ptrs(new const char*[options.size()+1]) {
m_ptrs(new const char*[options.size() + 1]) {
std::transform(m_options.begin(), m_options.end(), m_ptrs.get(), [&](const std::string& s) {
return s.data();
});
m_ptrs[options.size()] = nullptr;
}
char** get() const {
char** get() const noexcept {
return const_cast<char**>(m_ptrs.get());
}
@ -178,33 +190,37 @@ namespace gdalcpp {
SRS() :
m_spatial_reference() {
auto result = m_spatial_reference.SetWellKnownGeogCS("WGS84");
const auto result = m_spatial_reference.SetWellKnownGeogCS("WGS84");
if (result != OGRERR_NONE) {
throw gdal_error(std::string("can not initialize spatial reference system WGS84"), result);
throw gdal_error{std::string{"can not initialize spatial reference system WGS84"},
result};
}
}
explicit SRS(int epsg) :
m_spatial_reference() {
auto result = m_spatial_reference.importFromEPSG(epsg);
const auto result = m_spatial_reference.importFromEPSG(epsg);
if (result != OGRERR_NONE) {
throw gdal_error(std::string("can not initialize spatial reference system for EPSG:") + std::to_string(epsg), result);
throw gdal_error{std::string{"can not initialize spatial reference system for EPSG:"} + std::to_string(epsg),
result};
}
}
explicit SRS(const char* name) :
m_spatial_reference() {
auto result = m_spatial_reference.importFromProj4(name);
const auto result = m_spatial_reference.importFromProj4(name);
if (result != OGRERR_NONE) {
throw gdal_error(std::string("can not initialize spatial reference system '") + name + "'", result);
throw gdal_error{std::string{"can not initialize spatial reference system '"} + name + "'",
result};
}
}
explicit SRS(const std::string& name) :
m_spatial_reference() {
auto result = m_spatial_reference.importFromProj4(name.c_str());
const auto result = m_spatial_reference.importFromProj4(name.c_str());
if (result != OGRERR_NONE) {
throw gdal_error(std::string("can not initialize spatial reference system '") + name + "'", result);
throw gdal_error{std::string{"can not initialize spatial reference system '"} + name + "'",
result};
}
}
@ -212,11 +228,11 @@ namespace gdalcpp {
m_spatial_reference(spatial_reference) {
}
OGRSpatialReference& get() {
OGRSpatialReference& get() noexcept {
return m_spatial_reference;
}
const OGRSpatialReference& get() const {
const OGRSpatialReference& get() const noexcept {
return m_spatial_reference;
}
@ -257,11 +273,14 @@ namespace gdalcpp {
m_dataset(detail::Driver(driver_name).get().CreateDataSource(dataset_name.c_str(), m_options.get())) {
#endif
if (!m_dataset) {
throw gdal_error(std::string("failed to create dataset '") + dataset_name + "'", OGRERR_NONE, driver_name, dataset_name);
throw gdal_error{std::string{"failed to create dataset '"} + dataset_name + "'",
OGRERR_NONE,
driver_name,
dataset_name};
}
}
~Dataset() {
~Dataset() noexcept {
try {
if (m_edit_count > 0) {
commit_transaction();
@ -270,24 +289,24 @@ namespace gdalcpp {
}
}
const std::string& driver_name() const {
const std::string& driver_name() const noexcept {
return m_driver_name;
}
const std::string& dataset_name() const {
const std::string& dataset_name() const noexcept {
return m_dataset_name;
}
gdal_dataset_type& get() const {
gdal_dataset_type& get() const noexcept {
return *m_dataset;
}
SRS& srs() {
SRS& srs() noexcept {
return m_srs;
}
void exec(const char* sql) {
auto result = m_dataset->ExecuteSQL(sql, nullptr, nullptr);
const auto result = m_dataset->ExecuteSQL(sql, nullptr, nullptr);
if (result) {
m_dataset->ReleaseResultSet(result);
}
@ -334,7 +353,7 @@ namespace gdalcpp {
}
}
Dataset& enable_auto_transactions(uint64_t edits = 100000) {
Dataset& enable_auto_transactions(uint64_t edits = 100000) noexcept {
m_max_edit_count = edits;
return *this;
}
@ -362,20 +381,23 @@ namespace gdalcpp {
m_dataset(dataset),
m_layer(dataset.get().CreateLayer(layer_name.c_str(), &dataset.srs().get(), type, m_options.get())) {
if (!m_layer) {
throw gdal_error(std::string("failed to create layer '") + layer_name + "'", OGRERR_NONE,
dataset.driver_name(), dataset.dataset_name(), layer_name);
throw gdal_error{std::string{"failed to create layer '"} + layer_name + "'",
OGRERR_NONE,
dataset.driver_name(),
dataset.dataset_name(),
layer_name};
}
}
OGRLayer& get() {
OGRLayer& get() noexcept {
return *m_layer;
}
const OGRLayer& get() const {
const OGRLayer& get() const noexcept {
return *m_layer;
}
Dataset& dataset() const {
Dataset& dataset() const noexcept {
return m_dataset;
}
@ -389,8 +411,12 @@ namespace gdalcpp {
field.SetPrecision(precision);
if (m_layer->CreateField(&field) != OGRERR_NONE) {
throw gdal_error(std::string("failed to create field '") + field_name + "' in layer '" + name() + "'", OGRERR_NONE,
m_dataset.driver_name(), m_dataset.dataset_name(), name(), field_name);
throw gdal_error{std::string{"failed to create field '"} + field_name + "' in layer '" + name() + "'",
OGRERR_NONE,
m_dataset.driver_name(),
m_dataset.dataset_name(),
name(),
field_name};
}
return *this;
@ -398,18 +424,25 @@ namespace gdalcpp {
void create_feature(OGRFeature* feature) {
dataset().prepare_edit();
OGRErr result = m_layer->CreateFeature(feature);
const auto result = m_layer->CreateFeature(feature);
if (result != OGRERR_NONE) {
throw gdal_error(std::string("creating feature in layer '") + name() + "' failed", result, dataset().driver_name(), dataset().dataset_name());
throw gdal_error{std::string{"creating feature in layer '"} + name() + "' failed",
result,
dataset().driver_name(),
dataset().dataset_name()};
}
dataset().finalize_edit();
}
Layer& start_transaction() {
#if GDAL_VERSION_MAJOR < 2
OGRErr result = m_layer->StartTransaction();
const auto result = m_layer->StartTransaction();
if (result != OGRERR_NONE) {
throw gdal_error(std::string("starting transaction on layer '") + name() + "' failed", result, m_dataset.driver_name(), m_dataset.dataset_name(), name());
throw gdal_error{std::string{"starting transaction on layer '"} + name() + "' failed",
result,
m_dataset.driver_name(),
m_dataset.dataset_name(),
name()};
}
#endif
return *this;
@ -417,9 +450,13 @@ namespace gdalcpp {
Layer& commit_transaction() {
#if GDAL_VERSION_MAJOR < 2
OGRErr result = m_layer->CommitTransaction();
const auto result = m_layer->CommitTransaction();
if (result != OGRERR_NONE) {
throw gdal_error(std::string("committing transaction on layer '") + name() + "' failed", result, m_dataset.driver_name(), m_dataset.dataset_name(), name());
throw gdal_error{std::string{"committing transaction on layer '"} + name() + "' failed",
result,
m_dataset.driver_name(),
m_dataset.dataset_name(),
name()};
}
#endif
return *this;
@ -446,11 +483,14 @@ namespace gdalcpp {
m_layer(layer),
m_feature(OGRFeature::CreateFeature(m_layer.get().GetLayerDefn())) {
if (!m_feature) {
throw std::bad_alloc();
throw std::bad_alloc{};
}
OGRErr result = m_feature->SetGeometryDirectly(geometry.release());
const auto result = m_feature->SetGeometryDirectly(geometry.release());
if (result != OGRERR_NONE) {
throw gdal_error(std::string("setting feature geometry in layer '") + m_layer.name() + "' failed", result, m_layer.dataset().driver_name(), m_layer.dataset().dataset_name());
throw gdal_error{std::string{"setting feature geometry in layer '"} + m_layer.name() + "' failed",
result,
m_layer.dataset().driver_name(),
m_layer.dataset().dataset_name()};
}
}
@ -458,13 +498,13 @@ namespace gdalcpp {
m_layer.create_feature(m_feature.get());
}
template <class T>
template <typename T>
Feature& set_field(int n, T&& arg) {
m_feature->SetField(n, std::forward<T>(arg));
return *this;
}
template <class T>
template <typename T>
Feature& set_field(const char* name, T&& arg) {
m_feature->SetField(name, std::forward<T>(arg));
return *this;

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -72,10 +72,6 @@ namespace osmium {
*/
class AssemblerLegacy : public detail::BasicAssemblerWithTags {
void add_tags_to_area(osmium::builder::AreaBuilder& builder, const osmium::Way& way) const {
builder.add_item(way.tags());
}
void add_common_tags(osmium::builder::TagListBuilder& tl_builder, std::set<const osmium::Way*>& ways) const {
std::map<std::string, std::size_t> counter;
for (const osmium::Way* way : ways) {
@ -166,7 +162,7 @@ namespace osmium {
const bool area_okay = create_rings();
if (area_okay || config().create_empty_areas) {
add_tags_to_area(builder, way);
builder.add_item(way.tags());
}
if (area_okay) {
add_rings_to_area(builder);

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -103,9 +103,19 @@ namespace osmium {
*/
class BasicAssembler {
static constexpr const std::size_t max_split_locations = 100ULL;
// Maximum recursion depth, stops complex multipolygons from
// breaking everything.
enum : unsigned {
max_depth = 20U
};
struct slocation {
static constexpr const uint32_t invalid_item = 1u << 30u;
enum {
invalid_item = 1U << 30U
};
uint32_t item : 31;
uint32_t reverse : 1;
@ -269,7 +279,7 @@ namespace osmium {
using rings_stack = std::vector<rings_stack_element>;
void remove_duplicates(rings_stack& outer_rings) {
static void remove_duplicates(rings_stack& outer_rings) {
while (true) {
const auto it = std::adjacent_find(outer_rings.begin(), outer_rings.end());
if (it == outer_rings.end()) {
@ -350,7 +360,8 @@ namespace osmium {
std::cerr << " Segment is below (nesting=" << nesting << ")\n";
}
if (segment->ring()->is_outer()) {
const double y = ay + (by - ay) * (lx - ax) / double(bx - ax);
const double y = static_cast<double>(ay) +
static_cast<double>((by - ay) * (lx - ax)) / static_cast<double>(bx - ax);
if (debug()) {
std::cerr << " Segment belongs to outer ring (y=" << y << " ring=" << *segment->ring() << ")\n";
}
@ -500,7 +511,12 @@ namespace osmium {
void create_locations_list() {
m_locations.reserve(m_segment_list.size() * 2);
for (uint32_t n = 0; n < m_segment_list.size(); ++n) {
// static_cast is okay here: The 32bit limit is way past
// anything that makes sense here and even if there are
// 2^32 segments here, it would simply not go through
// all of them not building the multipolygon correctly.
assert(m_segment_list.size() < std::numeric_limits<uint32_t>::max());
for (uint32_t n = 0; n < static_cast<uint32_t>(m_segment_list.size()); ++n) {
m_locations.emplace_back(n, false);
m_locations.emplace_back(n, true);
}
@ -703,7 +719,13 @@ namespace osmium {
};
void find_candidates(std::vector<candidate>& candidates, std::unordered_set<osmium::Location>& loc_done, const std::vector<location_to_ring_map>& xrings, candidate& cand) {
struct exceeded_max_depth {};
void find_candidates(std::vector<candidate>& candidates, std::unordered_set<osmium::Location>& loc_done, const std::vector<location_to_ring_map>& xrings, const candidate& cand, unsigned depth = 0) {
if (depth > max_depth) {
throw exceeded_max_depth{};
}
if (debug()) {
std::cerr << " find_candidates sum=" << cand.sum << " start=" << cand.start_location << " stop=" << cand.stop_location << "\n";
for (const auto& ring : cand.rings) {
@ -741,13 +763,30 @@ namespace osmium {
if (debug()) {
std::cerr << " found candidate\n";
}
candidates.push_back(c);
if (candidates.empty()) {
candidates.push_back(c);
} else if (candidates.size() == 1) {
// add new candidate to vector, keep sorted
if (std::abs(c.sum) < std::abs(candidates.front().sum)) {
candidates.insert(candidates.begin(), c);
} else {
candidates.push_back(c);
}
} else {
// add new candidate if it has either smallest or largest area
if (std::abs(c.sum) < std::abs(candidates.front().sum)) {
candidates.front() = c;
} else if (std::abs(c.sum) > std::abs(candidates.back().sum)) {
candidates.back() = c;
}
}
} else if (loc_done.count(c.stop_location) == 0) {
if (debug()) {
std::cerr << " recurse...\n";
std::cerr << " recurse... (depth=" << depth << " candidates.size=" << candidates.size() << ")\n";
}
loc_done.insert(c.stop_location);
find_candidates(candidates, loc_done, xrings, c);
find_candidates(candidates, loc_done, xrings, c, depth + 1);
loc_done.erase(c.stop_location);
if (debug()) {
std::cerr << " ...back\n";
@ -790,7 +829,7 @@ namespace osmium {
ring.reset();
}
candidate cand{*ring_min, false};
const candidate cand{*ring_min, false};
// Locations we have visited while finding candidates, used
// to detect loops.
@ -799,7 +838,14 @@ namespace osmium {
loc_done.insert(cand.stop_location);
std::vector<candidate> candidates;
find_candidates(candidates, loc_done, xrings, cand);
try {
find_candidates(candidates, loc_done, xrings, cand);
} catch (const exceeded_max_depth&) {
if (m_config.debug_level > 0) {
std::cerr << " Exceeded max depth (" << static_cast<unsigned>(max_depth) << ")\n";
}
return false;
}
if (candidates.empty()) {
if (debug()) {
@ -828,26 +874,20 @@ 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::max_element(candidates.cbegin(), candidates.cend(), [](const candidate& lhs, const candidate& rhs) {
return std::abs(lhs.sum) < std::abs(rhs.sum);
});
const auto chosen_cand = ring_min_is_outer ? candidates.front() : candidates.back();
if (debug()) {
std::cerr << " Decided on: sum=" << chosen_cand->sum << "\n";
for (const auto& ring : chosen_cand->rings) {
std::cerr << " Decided on: sum=" << chosen_cand.sum << "\n";
for (const auto& ring : chosen_cand.rings) {
std::cerr << " " << ring.first.ring() << (ring.second ? " reverse" : "") << "\n";
}
}
// Join all (open) rings in the candidate to get one closed ring.
assert(chosen_cand->rings.size() > 1);
const auto& first_ring = chosen_cand->rings.front().first;
assert(chosen_cand.rings.size() > 1);
const auto& first_ring = chosen_cand.rings.front().first;
const ProtoRing& remaining_ring = first_ring.ring();
for (auto it = std::next(chosen_cand->rings.begin()); it != chosen_cand->rings.end(); ++it) {
for (auto it = std::next(chosen_cand.rings.begin()); it != chosen_cand.rings.end(); ++it) {
merge_two_rings(open_ring_its, first_ring, it->first);
}
@ -1077,9 +1117,20 @@ namespace osmium {
timer_simple_case.start();
create_rings_simple_case();
timer_simple_case.stop();
} else if (m_split_locations.size() > max_split_locations) {
if (m_config.debug_level > 0) {
std::cerr << " Ignoring polygon with "
<< m_split_locations.size()
<< " split locations (>"
<< max_split_locations
<< ")\n";
}
return false;
} else {
if (debug()) {
std::cerr << " Found split locations -> using complex algorithm\n";
if (m_config.debug_level > 0) {
std::cerr << " Found "
<< m_split_locations.size()
<< " split locations -> using complex algorithm\n";
}
++m_stats.area_touching_rings_case;

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -38,6 +38,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/node_ref.hpp>
#include <algorithm>
#include <array>
#include <cassert>
#include <cstdint>
#include <iosfwd>
@ -101,14 +102,10 @@ namespace osmium {
NodeRefSegment() noexcept = default;
NodeRefSegment(const osmium::NodeRef& nr1, const osmium::NodeRef& nr2, role_type role, const osmium::Way* way) noexcept :
m_first(nr1),
m_second(nr2),
m_first(nr1.location() < nr2.location() ? nr1 : nr2),
m_second(nr1.location() < nr2.location() ? nr2 : nr1),
m_way(way),
m_role(role) {
if (nr2.location() < nr1.location()) {
using std::swap;
swap(m_first, m_second);
}
}
/**
@ -195,7 +192,7 @@ namespace osmium {
}
const char* role_name() const noexcept {
static const char* names[] = { "unknown", "outer", "inner", "empty" };
static const std::array<const char*, 4> names = {{ "unknown", "outer", "inner", "empty" }};
return names[int(m_role)];
}
@ -205,7 +202,7 @@ namespace osmium {
/**
* The "determinant" of this segment. Used for calculating
* the winding order or a ring.
* the winding order of a ring.
*/
int64_t det() const noexcept {
const vec a{start()};
@ -348,13 +345,14 @@ namespace osmium {
osmium::Location location;
};
seg_loc sl[4];
sl[0] = {0, s1.first().location() };
sl[1] = {0, s1.second().location()};
sl[2] = {1, s2.first().location() };
sl[3] = {1, s2.second().location()};
std::array<seg_loc, 4> sl = {{
{0, s1.first().location() },
{0, s1.second().location()},
{1, s2.first().location() },
{1, s2.second().location()},
}};
std::sort(sl, sl+4, [](const seg_loc& lhs, const seg_loc& rhs) {
std::sort(sl.begin(), sl.end(), [](const seg_loc& lhs, const seg_loc& rhs) {
return lhs.location < rhs.location;
});

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -196,12 +196,14 @@ namespace osmium {
}
void join_forward(ProtoRing& other) {
m_segments.reserve(m_segments.size() + other.m_segments.size());
for (NodeRefSegment* segment : other.m_segments) {
add_segment_back(segment);
}
}
void join_backward(ProtoRing& other) {
m_segments.reserve(m_segments.size() + other.m_segments.size());
for (auto it = other.m_segments.rbegin(); it != other.m_segments.rend(); ++it) {
(*it)->reverse();
add_segment_back(*it);

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -147,14 +147,14 @@ namespace osmium {
m_debug(debug) {
}
~SegmentList() noexcept = default;
SegmentList(const SegmentList&) = delete;
SegmentList(SegmentList&&) = delete;
SegmentList& operator=(const SegmentList&) = delete;
SegmentList& operator=(SegmentList&&) = delete;
~SegmentList() noexcept = default;
/// The number of segments in the list.
std::size_t size() const noexcept {
return m_segments.size();
@ -181,7 +181,7 @@ namespace osmium {
return m_segments[n];
}
NodeRefSegment& operator[](std::size_t n) noexcept {
NodeRefSegment& operator[](const std::size_t n) noexcept {
assert(n < m_segments.size());
return m_segments[n];
}
@ -206,7 +206,7 @@ namespace osmium {
* Enable or disable debug output to stderr. This is used
* for debugging libosmium itself.
*/
void enable_debug_output(bool debug = true) noexcept {
void enable_debug_output(const bool debug = true) noexcept {
m_debug = debug;
}

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -68,8 +68,6 @@ namespace osmium {
detail::BasicAssembler(config) {
}
~GeomAssembler() noexcept = default;
/**
* Assemble an area from the given way.
*

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -70,6 +70,8 @@ namespace osmium {
*
* @tparam TAssembler Multipolygon Assembler class.
* @pre The Ids of all objects must be unique in the input data.
*
* @deprecated Use MultipolygonManager instead.
*/
template <typename TAssembler>
class MultipolygonCollector : public osmium::relations::Collector<MultipolygonCollector<TAssembler>, false, true, false> {
@ -83,8 +85,13 @@ namespace osmium {
area_stats m_stats;
static constexpr size_t initial_output_buffer_size = 1024 * 1024;
static constexpr size_t max_buffer_size_for_flush = 100 * 1024;
enum {
initial_output_buffer_size = 1024UL * 1024UL
};
enum {
max_buffer_size_for_flush = 100UL * 1024UL
};
void flush_output_buffer() {
if (this->callback()) {

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -63,8 +63,8 @@ namespace osmium {
/**
* This class collects all data needed for creating areas from
* relations tagged with type=multipolygon or type=boundary.
* Most of its functionality is derived from the parent class
* osmium::relations::Collector.
* Most of its functionality is derived from the parent template class
* osmium::relations::RelationsManager.
*
* The actual assembling of the areas is done by the assembler
* class given as template argument.

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -93,6 +93,10 @@ namespace osmium {
m_object_id = object_id;
}
osmium::object_id_type object_id() const noexcept {
return m_object_id;
}
void set_nodes(size_t nodes) noexcept {
m_nodes = nodes;
}

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -45,6 +45,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/relation.hpp>
#include <osmium/osm/timestamp.hpp>
#include <osmium/osm/types.hpp>
#include <osmium/util/string.hpp>
#include <cstddef>
#include <cstdint>
@ -226,8 +227,8 @@ namespace osmium {
OSMIUM_ATTRIBUTE(node_handler, _location, osmium::Location)
constexpr explicit _location(const osmium::Location& value) noexcept :
type_wrapper(value) {}
explicit _location(double lat, double lon) :
type_wrapper(osmium::Location{lat, lon}) {}
explicit _location(double lon, double lat) :
type_wrapper(osmium::Location{lon, lat}) {}
};
OSMIUM_ATTRIBUTE(entity_handler, _user, const char*)
@ -254,6 +255,10 @@ namespace osmium {
m_role(role) {
}
member_type(char type, osmium::object_id_type ref, const char* role = "") noexcept :
member_type(osmium::char_to_item_type(type), ref, role) {
}
constexpr osmium::item_type type() const noexcept {
return m_type;
}
@ -282,6 +287,10 @@ namespace osmium {
m_role(std::move(role)) {
}
member_type_string(char type, osmium::object_id_type ref, std::string&& role) noexcept :
member_type_string(osmium::char_to_item_type(type), ref, std::forward<std::string>(role)) {
}
osmium::item_type type() const noexcept {
return m_type;
}
@ -360,6 +369,15 @@ namespace osmium {
type_wrapper(std::make_pair(key, val)) {}
explicit _tag(const std::string& key, const std::string& val) :
type_wrapper(std::make_pair(key.c_str(), val.c_str())) {}
explicit _tag(const char* const key_value) :
type_wrapper(pair_of_cstrings{key_value, nullptr}) {}
explicit _tag(const std::string& key_value) :
type_wrapper(pair_of_cstrings{key_value.c_str(), nullptr}) {}
};
OSMIUM_ATTRIBUTE(tags_handler, _t, const char*)
explicit _t(const char *tags) :
type_wrapper(tags) {}
};
template <typename TTagIterator>
@ -659,7 +677,19 @@ namespace osmium {
}
static void set_value(TagListBuilder& builder, const attr::_tag& tag) {
builder.add_tag(tag.value);
if (tag.value.second != nullptr) {
builder.add_tag(tag.value);
return;
}
const char* key = tag.value.first;
auto const equal_sign = std::strchr(key, '=');
if (!equal_sign) {
builder.add_tag(key, "");
return;
}
const char* value = equal_sign + 1;
builder.add_tag(key, equal_sign - key,
value, std::strlen(value));
}
template <typename TIterator>
@ -669,6 +699,21 @@ namespace osmium {
}
}
static void set_value(TagListBuilder& builder, const attr::_t& tags) {
const auto taglist = osmium::split_string(tags.value, ',', true);
for (const auto& tag : taglist) {
const std::size_t pos = tag.find_first_of('=');
if (pos == std::string::npos) {
builder.add_tag(tag, "");
} else {
const char* value = tag.c_str() + pos + 1;
builder.add_tag(tag.c_str(), pos,
value, tag.size() - pos - 1);
}
}
}
}; // struct tags_handler
struct nodes_handler {
@ -764,7 +809,7 @@ namespace osmium {
template <typename TBuilder, typename THandler, typename... TArgs>
inline typename std::enable_if<is_handled_by<THandler, TArgs...>::value>::type
add_list(osmium::builder::Builder& parent, const TArgs&... args) {
TBuilder builder(parent.buffer(), &parent);
TBuilder builder{parent.buffer(), &parent};
(void)std::initializer_list<int>{
(THandler::set_value(builder, args), 0)...
};
@ -792,7 +837,7 @@ namespace osmium {
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...);
@ -815,7 +860,7 @@ namespace osmium {
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...);
@ -839,7 +884,7 @@ namespace osmium {
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...);
@ -863,7 +908,7 @@ namespace osmium {
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...);
@ -887,7 +932,7 @@ namespace osmium {
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...);
@ -914,7 +959,7 @@ namespace osmium {
static_assert(detail::are_all_handled_by<detail::nodes_handler, TArgs...>::value, "Attribute not allowed in add_way_node_list()");
{
WayNodeListBuilder builder(buffer);
WayNodeListBuilder builder{buffer};
(void)std::initializer_list<int>{
(detail::nodes_handler::set_value(builder, args), 0)...
};
@ -936,7 +981,7 @@ namespace osmium {
static_assert(detail::are_all_handled_by<detail::tags_handler, TArgs...>::value, "Attribute not allowed in add_tag_list()");
{
TagListBuilder builder(buffer);
TagListBuilder builder{buffer};
(void)std::initializer_list<int>{
(detail::tags_handler::set_value(builder, args), 0)...
};

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -65,7 +65,7 @@ namespace osmium {
explicit Builder(osmium::memory::Buffer& buffer, Builder* parent, osmium::memory::item_size_type size) :
m_buffer(buffer),
m_parent(parent),
m_item_offset(buffer.written()) {
m_item_offset(buffer.written() - buffer.committed()) {
reserve_space(size);
assert(buffer.is_aligned());
if (m_parent) {
@ -80,7 +80,7 @@ namespace osmium {
}
#ifdef NDEBUG
~Builder() = default;
~Builder() noexcept = default;
#else
~Builder() noexcept {
m_buffer.decrement_builder_count();
@ -88,7 +88,7 @@ namespace osmium {
#endif
osmium::memory::Item& item() const {
return *reinterpret_cast<osmium::memory::Item*>(m_buffer.data() + m_item_offset);
return *reinterpret_cast<osmium::memory::Item*>(m_buffer.data() + m_buffer.committed() + m_item_offset);
}
unsigned char* reserve_space(std::size_t size) {

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -49,6 +49,9 @@ namespace osmium {
* An input iterator wrapping any iterator over OSMObjects. When
* dereferenced it will yield DiffObject objects pointing to the
* underlying OSMObjects.
*
* Note that this class uses a mutable member variable internally.
* It can not be used safely in multiple threads!
*/
template <typename TBasicIterator>
class DiffIterator {

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -35,7 +35,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/geom/coordinates.hpp>
#include <osmium/geom/util.hpp>
#include <osmium/osm/node_ref.hpp>
#include <osmium/osm/node_ref_list.hpp>
#include <osmium/osm/way.hpp>
#include <cmath>
@ -63,13 +63,13 @@ namespace osmium {
*
* @pre @code c1.valid() && c2.valid() @endcode
*/
inline double distance(const osmium::geom::Coordinates& c1, const osmium::geom::Coordinates& c2) {
double lonh = sin(deg_to_rad(c1.x - c2.x) * 0.5);
inline double distance(const osmium::geom::Coordinates& c1, const osmium::geom::Coordinates& c2) noexcept {
double lonh = std::sin(deg_to_rad(c1.x - c2.x) * 0.5);
lonh *= lonh;
double lath = sin(deg_to_rad(c1.y - c2.y) * 0.5);
double lath = std::sin(deg_to_rad(c1.y - c2.y) * 0.5);
lath *= lath;
const double tmp = cos(deg_to_rad(c1.y)) * cos(deg_to_rad(c2.y));
return 2.0 * EARTH_RADIUS_IN_METERS * asin(sqrt(lath + tmp * lonh));
const double tmp = std::cos(deg_to_rad(c1.y)) * std::cos(deg_to_rad(c2.y));
return 2.0 * EARTH_RADIUS_IN_METERS * std::asin(std::sqrt(lath + tmp * lonh));
}
/**
@ -87,6 +87,21 @@ namespace osmium {
return sum_length;
}
/**
* Calculate length of node list.
*/
inline double distance(const osmium::NodeRefList& nrl) {
double sum_length = 0;
for (auto it = nrl.begin(); it != nrl.end(); ++it) {
if (std::next(it) != nrl.end()) {
sum_length += distance(it->location(), std::next(it)->location());
}
}
return sum_length;
}
} // namespace haversine
} // namespace geom

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -49,7 +49,7 @@ namespace osmium {
constexpr double earth_radius_for_epsg3857 = 6378137.0;
constexpr double max_coordinate_epsg3857 = 20037508.34;
constexpr inline double lon_to_x(double lon) {
constexpr inline double lon_to_x(double lon) noexcept {
return earth_radius_for_epsg3857 * deg_to_rad(lon);
}
@ -116,6 +116,9 @@ namespace osmium {
* Convert the coordinates from WGS84 lon/lat to web mercator.
*
* @pre @code c.valid() @endcode
* @pre Coordinates must be in valid range, longitude between
* -180 and +180 degree, latitude between -MERCATOR_MAX_LAT
* and MERCATOR_MAX_LAT.
*/
inline Coordinates lonlat_to_mercator(const Coordinates& c) {
return Coordinates{detail::lon_to_x(c.x), detail::lat_to_y(c.y)};
@ -125,6 +128,8 @@ namespace osmium {
* Convert the coordinates from web mercator to WGS84 lon/lat.
*
* @pre @code c.valid() @endcode
* @pre Coordinates must be in valid range (longitude and
* latidude between -/+20037508.34).
*/
inline Coordinates mercator_to_lonlat(const Coordinates& c) {
return Coordinates{detail::x_to_lon(c.x), detail::y_to_lat(c.y)};
@ -145,6 +150,13 @@ namespace osmium {
MercatorProjection() { // NOLINT(hicpp-use-equals-default, modernize-use-equals-default)
}
/**
* Do coordinate transformation.
*
* @pre Coordinates must be in valid range, longitude between
* -180 and +180 degree, latitude between -MERCATOR_MAX_LAT
* and MERCATOR_MAX_LAT.
*/
Coordinates operator()(osmium::Location location) const {
return Coordinates{detail::lon_to_x(location.lon()), detail::lat_to_y(location.lat())};
}

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -46,8 +46,15 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/geom/mercator_projection.hpp>
#include <osmium/geom/util.hpp>
#include <osmium/osm/location.hpp>
#include <osmium/util/compatibility.hpp>
#include <proj_api.h>
#ifdef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
# include <proj_api.h>
#else
# define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
# include <proj_api.h>
# undef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
#endif
#include <memory>
#include <string>
@ -58,6 +65,8 @@ namespace osmium {
/**
* C++ wrapper for a Coordinate Reference System of the proj library.
*
* @deprecated Only supports the old PROJ API.
*/
class CRS {
@ -110,9 +119,11 @@ namespace osmium {
* Coordinates have to be in radians and are produced in radians.
*
* @throws osmium::projection_error if the projection fails
*
* @deprecated Only supports the old PROJ API.
*/
// cppcheck-suppress passedByValue (because c is small and we want to change it)
inline Coordinates transform(const CRS& src, const CRS& dest, Coordinates c) {
inline OSMIUM_DEPRECATED Coordinates transform(const CRS& src, const CRS& dest, Coordinates c) {
const int result = pj_transform(src.get(), dest.get(), 1, 1, &c.x, &c.y, nullptr);
if (result != 0) {
throw osmium::projection_error{std::string{"projection failed: "} + pj_strerrno(result)};
@ -130,6 +141,8 @@ namespace osmium {
* implementation of the Mercator projection is used, otherwise this
* falls back to using the proj.4 library. Note that this "magic" does
* not work if you use any of the constructors taking a string.
*
* @deprecated Only supports the old PROJ API.
*/
class Projection {
@ -158,6 +171,12 @@ namespace osmium {
m_crs_user(epsg) {
}
/**
* Do coordinate transformation.
*
* @pre Location must be in valid range (depends on projection
* used).
*/
Coordinates operator()(osmium::Location location) const {
if (m_epsg == 4326) {
return Coordinates{location.lon(), location.lat()};

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -58,7 +58,7 @@ namespace osmium {
* level.
*/
inline constexpr uint32_t num_tiles_in_zoom(uint32_t zoom) noexcept {
return 1u << zoom;
return 1U << zoom;
}
/**
@ -98,6 +98,10 @@ namespace osmium {
*/
struct Tile {
enum {
max_zoom = 30U
};
/// x coordinate
uint32_t x;
@ -119,7 +123,7 @@ namespace osmium {
x(tx),
y(ty),
z(zoom) {
assert(zoom <= 30u);
assert(zoom <= max_zoom);
assert(x < num_tiles_in_zoom(zoom));
assert(y < num_tiles_in_zoom(zoom));
}
@ -134,7 +138,7 @@ namespace osmium {
*/
explicit Tile(uint32_t zoom, const osmium::Location& location) :
z(zoom) {
assert(zoom <= 30u);
assert(zoom <= max_zoom);
assert(location.valid());
const auto coordinates = lonlat_to_mercator(location);
x = mercx_to_tilex(zoom, coordinates.x);
@ -151,7 +155,7 @@ namespace osmium {
*/
explicit Tile(uint32_t zoom, const osmium::geom::Coordinates& coordinates) :
z(zoom) {
assert(zoom <= 30u);
assert(zoom <= max_zoom);
x = mercx_to_tilex(zoom, coordinates.x);
y = mercy_to_tiley(zoom, coordinates.y);
}
@ -162,7 +166,7 @@ namespace osmium {
* each be between 0 and 2^zoom-1.
*/
bool valid() const noexcept {
if (z > 30) {
if (z > max_zoom) {
return false;
}
const auto max = num_tiles_in_zoom(z);

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -35,7 +35,6 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/geom/coordinates.hpp>
#include <osmium/geom/factory.hpp>
#include <osmium/util/cast.hpp>
#include <osmium/util/endian.hpp>
#include <algorithm>
@ -70,8 +69,8 @@ namespace osmium {
out.reserve(str.size() * 2);
for (char c : str) {
out += lookup_hex[(static_cast<unsigned int>(c) >> 4u) & 0xfu];
out += lookup_hex[ static_cast<unsigned int>(c) & 0xfu];
out += lookup_hex[(static_cast<unsigned int>(c) >> 4U) & 0xfU];
out += lookup_hex[ static_cast<unsigned int>(c) & 0xfU];
}
return out;

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -46,7 +46,9 @@ namespace osmium {
namespace detail {
constexpr size_t mmap_vector_size_increment = 1024 * 1024;
enum {
mmap_vector_size_increment = 1024UL * 1024UL
};
/**
* This is a base class for implementing classes that look like
@ -58,12 +60,12 @@ namespace osmium {
protected:
size_t m_size = 0;
std::size_t m_size = 0;
osmium::TypedMemoryMapping<T> m_mapping;
public:
mmap_vector_base(int fd, size_t capacity, size_t size = 0) :
mmap_vector_base(const int fd, const std::size_t capacity, const std::size_t size = 0) :
m_size(size),
m_mapping(capacity, osmium::MemoryMapping::mapping_mode::write_shared, fd) {
assert(size <= capacity);
@ -71,7 +73,7 @@ namespace osmium {
shrink_to_fit();
}
explicit mmap_vector_base(size_t capacity = mmap_vector_size_increment) :
explicit mmap_vector_base(const std::size_t capacity = mmap_vector_size_increment) :
m_mapping(capacity) {
std::fill_n(data(), capacity, osmium::index::empty_value<T>());
}
@ -88,11 +90,11 @@ namespace osmium {
m_mapping.unmap();
}
size_t capacity() const noexcept {
std::size_t capacity() const noexcept {
return m_mapping.size();
}
size_t size() const noexcept {
std::size_t size() const noexcept {
return m_size;
}
@ -108,17 +110,17 @@ namespace osmium {
return m_mapping.begin();
}
const_reference operator[](size_t n) const {
const_reference operator[](const std::size_t n) const {
assert(n < m_size);
return data()[n];
}
reference operator[](size_t n) {
reference operator[](const std::size_t n) {
assert(n < m_size);
return data()[n];
}
value_type at(size_t n) const {
value_type at(const std::size_t n) const {
if (n >= m_size) {
throw std::out_of_range{"out of range"};
}
@ -140,17 +142,17 @@ namespace osmium {
data()[m_size - 1] = value;
}
void reserve(size_t new_capacity) {
void reserve(const std::size_t new_capacity) {
if (new_capacity > capacity()) {
const size_t old_capacity = capacity();
const std::size_t old_capacity = capacity();
m_mapping.resize(new_capacity);
std::fill(data() + old_capacity, data() + new_capacity, osmium::index::empty_value<value_type>());
}
}
void resize(size_t new_size) {
void resize(const std::size_t new_size) {
if (new_size > capacity()) {
reserve(new_size + osmium::detail::mmap_vector_size_increment);
reserve(new_size + mmap_vector_size_increment);
}
m_size = new_size;
}

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -53,7 +53,7 @@ namespace osmium {
template <typename T>
class mmap_vector_file : public mmap_vector_base<T> {
static std::size_t filesize(int fd) {
static std::size_t filesize(const int fd) {
const auto size = osmium::file_size(fd);
if (size % sizeof(T) != 0) {
@ -71,10 +71,10 @@ namespace osmium {
osmium::detail::mmap_vector_size_increment) {
}
explicit mmap_vector_file(int fd) :
explicit mmap_vector_file(const int fd) :
mmap_vector_base<T>(
fd,
std::max(osmium::detail::mmap_vector_size_increment, filesize(fd)),
std::max(static_cast<std::size_t>(mmap_vector_size_increment), filesize(fd)),
filesize(fd)) {
}

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -39,8 +39,10 @@ DEALINGS IN THE SOFTWARE.
#include <algorithm>
#include <cstddef>
#include <memory>
#include <utility>
namespace osmium {
namespace index {
@ -221,6 +223,26 @@ namespace osmium {
std::sort(m_vector.begin(), m_vector.end());
}
void dump_as_array(const int fd) final {
constexpr const size_t value_size = sizeof(TValue);
constexpr const size_t buffer_size = (10L * 1024L * 1024L) / value_size;
std::unique_ptr<TValue[]> output_buffer{new TValue[buffer_size]};
size_t buffer_start_id = 0;
for (auto it = cbegin(); it != cend();) {
std::fill_n(output_buffer.get(), buffer_size, osmium::index::empty_value<TValue>());
size_t offset = 0;
for (; offset < buffer_size && it != end(); ++offset) {
if (buffer_start_id + offset == it->first) {
output_buffer[offset] = it->second;
++it;
}
}
osmium::io::detail::reliable_write(fd, reinterpret_cast<const unsigned char*>(output_buffer.get()), offset * value_size);
buffer_start_id += buffer_size;
}
}
void dump_as_list(const int fd) final {
osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(m_vector.data()), byte_size());
}

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -37,6 +37,7 @@ DEALINGS IN THE SOFTWARE.
#include <osmium/osm/types.hpp>
#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <cstring>
@ -95,33 +96,47 @@ namespace osmium {
}; // class IdSet
template <typename T>
namespace detail {
// 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.
enum : std::size_t {
default_chunk_bits = 22U
};
} // namespace detail
template <typename T, std::size_t chunk_bits = detail::default_chunk_bits>
class IdSetDense;
/**
* Const_iterator for iterating over a IdSetDense.
*/
template <typename T>
template <typename T, std::size_t chunk_bits>
class IdSetDenseIterator {
static_assert(std::is_unsigned<T>::value, "Needs unsigned type");
static_assert(sizeof(T) >= 4, "Needs at least 32bit type");
const IdSetDense<T>* m_set;
using id_set = IdSetDense<T, chunk_bits>;
const id_set* m_set;
T m_value;
T m_last;
void next() noexcept {
while (m_value != m_last && !m_set->get(m_value)) {
const T cid = IdSetDense<T>::chunk_id(m_value);
const T cid = id_set::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);
m_value = (cid + 1) << (chunk_bits + 3);
} else {
const auto slot = m_set->m_data[cid][IdSetDense<T>::offset(m_value)];
const auto slot = m_set->m_data[cid][id_set::offset(m_value)];
if (slot == 0) {
m_value += 8;
m_value &= ~0x7ull;
m_value &= ~0x7ULL;
} else {
++m_value;
}
@ -136,14 +151,14 @@ namespace osmium {
using pointer = value_type*;
using reference = value_type&;
IdSetDenseIterator(const IdSetDense<T>* set, T value, T last) noexcept :
IdSetDenseIterator(const id_set* set, T value, T last) noexcept :
m_set(set),
m_value(value),
m_last(last) {
next();
}
IdSetDenseIterator<T>& operator++() noexcept {
IdSetDenseIterator& operator++() noexcept {
if (m_value != m_last) {
++m_value;
next();
@ -151,17 +166,17 @@ namespace osmium {
return *this;
}
IdSetDenseIterator<T> operator++(int) noexcept {
IdSetDenseIterator<T> tmp{*this};
IdSetDenseIterator operator++(int) noexcept {
IdSetDenseIterator tmp{*this};
operator++();
return tmp;
}
bool operator==(const IdSetDenseIterator<T>& rhs) const noexcept {
bool operator==(const IdSetDenseIterator& rhs) const noexcept {
return m_set == rhs.m_set && m_value == rhs.m_value;
}
bool operator!=(const IdSetDenseIterator<T>& rhs) const noexcept {
bool operator!=(const IdSetDenseIterator& rhs) const noexcept {
return !(*this == rhs);
}
@ -179,34 +194,31 @@ namespace osmium {
* and larger Id sets. If it is not used, no memory is allocated at
* all.
*/
template <typename T>
template <typename T, std::size_t chunk_bits>
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>;
friend class IdSetDenseIterator<T, chunk_bits>;
// 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 std::size_t chunk_bits = 22u;
constexpr static const std::size_t chunk_size = 1u << chunk_bits;
enum : std::size_t {
chunk_size = 1U << chunk_bits
};
std::vector<std::unique_ptr<unsigned char[]>> m_data;
T m_size = 0;
static std::size_t chunk_id(T id) noexcept {
return id >> (chunk_bits + 3u);
return id >> (chunk_bits + 3U);
}
static std::size_t offset(T id) noexcept {
return (id >> 3u) & ((1u << chunk_bits) - 1u);
return (id >> 3U) & ((1U << chunk_bits) - 1U);
}
static unsigned char bitmask(T id) noexcept {
return 1u << (id & 0x7u);
static unsigned int bitmask(T id) noexcept {
return 1U << (id & 0x7U);
}
T last() const noexcept {
@ -230,10 +242,43 @@ namespace osmium {
public:
using const_iterator = IdSetDenseIterator<T>;
using const_iterator = IdSetDenseIterator<T, chunk_bits>;
friend void swap(IdSetDense& first, IdSetDense& second) noexcept {
using std::swap;
swap(first.m_data, second.m_data);
swap(first.m_size, second.m_size);
}
IdSetDense() = default;
IdSetDense(const IdSetDense& other) :
IdSet<T>(other) {
m_data.reserve(other.m_data.size());
for (const auto& ptr: other.m_data) {
if (ptr) {
m_data.emplace_back(new unsigned char[chunk_size]);
::memcpy(m_data.back().get(), ptr.get(), chunk_size);
} else {
m_data.emplace_back();
}
}
m_size = other.m_size;
}
IdSetDense& operator=(IdSetDense other) {
swap(*this, other);
return *this;
}
IdSetDense(IdSetDense&&) noexcept = default;
// This should really be noexcept, but GCC 4.8 doesn't like it.
// NOLINTNEXTLINE(hicpp-noexcept-move, performance-noexcept-move-constructor)
IdSetDense& operator=(IdSetDense&&) = default;
~IdSetDense() noexcept override = default;
/**
* Add the Id to the set if it is not already in there.
*
@ -284,7 +329,7 @@ namespace osmium {
if (chunk_id(id) >= m_data.size()) {
return false;
}
auto* r = m_data[chunk_id(id)].get();
const auto* r = m_data[chunk_id(id)].get();
if (!r) {
return false;
}
@ -317,11 +362,11 @@ namespace osmium {
return m_data.size() * chunk_size;
}
IdSetDenseIterator<T> begin() const {
const_iterator begin() const {
return {this, 0, last()};
}
IdSetDenseIterator<T> end() const {
const_iterator end() const {
return {this, last(), last()};
}
@ -342,7 +387,9 @@ namespace osmium {
* Add the given Id to the set.
*/
void set(T id) final {
m_data.push_back(id);
if (m_data.empty() || m_data.back() != id) {
m_data.push_back(id);
}
}
/**
@ -385,7 +432,8 @@ namespace osmium {
/**
* Sort the internal vector and remove any duplicates. Call this
* before using size(), get_binary_search() or using an iterator.
* before using size(), get_binary_search(), merge_sorted() or
* using an iterator.
*/
void sort_unique() {
std::sort(m_data.begin(), m_data.end());
@ -408,6 +456,22 @@ namespace osmium {
return m_data.capacity() * sizeof(T);
}
/**
* Merge the other set into this one. The result is sorted.
*
* @pre Both sets must be sorted and must not contain any
* duplicates. Call sort_unique() if you are not sure.
*/
void merge_sorted(const IdSetSmall<T>& other) {
std::vector<T> new_data;
new_data.reserve(m_data.size() + other.m_data.size());
std::set_union(m_data.cbegin(), m_data.cend(),
other.m_data.cbegin(), other.m_data.cend(),
std::back_inserter(new_data));
using std::swap;
swap(new_data, m_data);
}
/// Iterator type. There is no non-const iterator.
using const_iterator = typename std::vector<T>::const_iterator;
@ -435,7 +499,7 @@ namespace osmium {
using id_set_type = IdSetType<osmium::unsigned_object_id_type>;
id_set_type m_sets[3];
std::array<id_set_type, 3> m_sets;
public:

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003
@ -118,7 +118,7 @@ namespace osmium {
virtual ~Map() noexcept = default;
virtual void reserve(const size_t /*size*/) {
virtual void reserve(const std::size_t /*size*/) {
// default implementation is empty
}
@ -151,7 +151,7 @@ namespace osmium {
* accurate. You can not use this to find out how much memory the
* storage uses. Use used_memory() for that.
*/
virtual size_t size() const = 0;
virtual std::size_t size() const = 0;
/**
* Get the memory used for this storage in bytes. Note that this
@ -160,7 +160,7 @@ namespace osmium {
* the main memory used, for storage classes storing data on disk
* this is the memory used on disk.
*/
virtual size_t used_memory() const = 0;
virtual std::size_t used_memory() const = 0;
/**
* Clear memory used for this storage. After this you can not
@ -210,8 +210,6 @@ namespace osmium {
MapFactory() = default;
~MapFactory() = default;
public:
MapFactory(const MapFactory&) = delete;
@ -220,6 +218,8 @@ namespace osmium {
MapFactory(MapFactory&&) = delete;
MapFactory& operator=(MapFactory&&) = delete;
~MapFactory() = default;
static MapFactory<id_type, value_type>& instance() {
static MapFactory<id_type, value_type> factory;
return factory;

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

View File

@ -3,9 +3,9 @@
/*
This file is part of Osmium (http://osmcode.org/libosmium).
This file is part of Osmium (https://osmcode.org/libosmium).
Copyright 2013-2018 Jochen Topf <jochen@topf.org> and others (see README).
Copyright 2013-2020 Jochen Topf <jochen@topf.org> and others (see README).
Boost Software License - Version 1.0 - August 17th, 2003

Some files were not shown because too many files have changed in this diff Show More