Remove libosmium
This commit is contained in:
parent
042740877c
commit
ae85d86d8f
2
third_party/libosmium/.gitignore
vendored
2
third_party/libosmium/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
*.swp
|
|
||||||
.ycm_extra_conf.pyc
|
|
159
third_party/libosmium/.travis.yml
vendored
159
third_party/libosmium/.travis.yml
vendored
@ -1,159 +0,0 @@
|
|||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Configuration for continuous integration service at travis-ci.org
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
language: cpp
|
|
||||||
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
|
|
||||||
# 1/ Linux Clang Builds
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['llvm-toolchain-precise-3.5', 'ubuntu-toolchain-r-test', 'boost-latest']
|
|
||||||
packages: ['clang-3.5', 'libboost1.55-all-dev', 'libgdal-dev', 'libgeos++-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin']
|
|
||||||
env: COMPILER='clang++-3.5' BUILD_TYPE='Release'
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['llvm-toolchain-precise-3.5', 'ubuntu-toolchain-r-test', 'boost-latest']
|
|
||||||
packages: ['clang-3.5', 'libboost1.55-all-dev', 'libgdal-dev', 'libgeos++-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin']
|
|
||||||
env: COMPILER='clang++-3.5' BUILD_TYPE='Dev'
|
|
||||||
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test', 'boost-latest']
|
|
||||||
packages: ['clang-3.6', 'libboost1.55-all-dev', 'libgdal-dev', 'libgeos++-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin']
|
|
||||||
env: COMPILER='clang++-3.6' BUILD_TYPE='Release'
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test', 'boost-latest']
|
|
||||||
packages: ['clang-3.6', 'libboost1.55-all-dev', 'libgdal-dev', 'libgeos++-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin']
|
|
||||||
env: COMPILER='clang++-3.6' BUILD_TYPE='Dev'
|
|
||||||
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['llvm-toolchain-precise-3.7', 'ubuntu-toolchain-r-test', 'boost-latest']
|
|
||||||
packages: ['clang-3.7', 'libboost1.55-all-dev', 'libgdal-dev', 'libgeos++-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin']
|
|
||||||
env: COMPILER='clang++-3.7' BUILD_TYPE='Release'
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
compiler: clang
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['llvm-toolchain-precise-3.7', 'ubuntu-toolchain-r-test', 'boost-latest']
|
|
||||||
packages: ['clang-3.7', 'libboost1.55-all-dev', 'libgdal-dev', 'libgeos++-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin']
|
|
||||||
env: COMPILER='clang++-3.7' BUILD_TYPE='Dev'
|
|
||||||
|
|
||||||
|
|
||||||
# 2/ Linux GCC Builds
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['ubuntu-toolchain-r-test', 'boost-latest']
|
|
||||||
packages: ['g++-4.8', 'libboost1.55-all-dev', 'libgdal-dev', 'libgeos++-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin']
|
|
||||||
env: COMPILER='g++-4.8' COMPILER_FLAGS='-Wno-return-type' BUILD_TYPE='Release'
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['ubuntu-toolchain-r-test', 'boost-latest']
|
|
||||||
packages: ['g++-4.8', 'libboost1.55-all-dev', 'libgdal-dev', 'libgeos++-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin']
|
|
||||||
env: COMPILER='g++-4.8' COMPILER_FLAGS='-Wno-return-type' BUILD_TYPE='Dev'
|
|
||||||
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['ubuntu-toolchain-r-test', 'boost-latest']
|
|
||||||
packages: ['g++-4.9', 'libboost1.55-all-dev', 'libgdal-dev', 'libgeos++-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin']
|
|
||||||
env: COMPILER='g++-4.9' BUILD_TYPE='Release'
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['ubuntu-toolchain-r-test', 'boost-latest']
|
|
||||||
packages: ['g++-4.9', 'libboost1.55-all-dev', 'libgdal-dev', 'libgeos++-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin']
|
|
||||||
env: COMPILER='g++-4.9' BUILD_TYPE='Dev'
|
|
||||||
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['ubuntu-toolchain-r-test', 'boost-latest']
|
|
||||||
packages: ['g++-5', 'libboost1.55-all-dev', 'libgdal-dev', 'libgeos++-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin']
|
|
||||||
env: COMPILER='g++-5' BUILD_TYPE='Release'
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
compiler: gcc
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['ubuntu-toolchain-r-test', 'boost-latest']
|
|
||||||
packages: ['g++-5', 'libboost1.55-all-dev', 'libgdal-dev', 'libgeos++-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin']
|
|
||||||
env: COMPILER='g++-5' BUILD_TYPE='Dev'
|
|
||||||
|
|
||||||
|
|
||||||
# 3/ OSX Clang Builds
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode6.4
|
|
||||||
compiler: clang
|
|
||||||
env: COMPILER='clang++' BUILD_TYPE='Dev'
|
|
||||||
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode6.4
|
|
||||||
compiler: clang
|
|
||||||
env: COMPILER='clang++' BUILD_TYPE='Release'
|
|
||||||
|
|
||||||
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode7
|
|
||||||
compiler: clang
|
|
||||||
env: COMPILER='clang++' BUILD_TYPE='Dev'
|
|
||||||
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode7
|
|
||||||
compiler: clang
|
|
||||||
env: COMPILER='clang++' BUILD_TYPE='Release'
|
|
||||||
|
|
||||||
|
|
||||||
install:
|
|
||||||
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
|
|
||||||
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
|
|
||||||
- git clone --quiet --depth 1 https://github.com/osmcode/osm-testdata.git
|
|
||||||
- |
|
|
||||||
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
|
||||||
brew remove gdal
|
|
||||||
brew install cmake boost google-sparsehash gdal
|
|
||||||
fi
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- cd ${TRAVIS_BUILD_DIR}
|
|
||||||
- mkdir build && cd build
|
|
||||||
- CXX=${COMPILER} CXXFLAGS=${COMPILER_FLAGS} cmake -LA .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DOSM_TESTDATA="${TRAVIS_BUILD_DIR}/deps/osm-testdata"
|
|
||||||
|
|
||||||
script:
|
|
||||||
- make VERBOSE=1
|
|
||||||
- ctest --output-on-failure
|
|
||||||
|
|
48
third_party/libosmium/.ycm_extra_conf.py
vendored
48
third_party/libosmium/.ycm_extra_conf.py
vendored
@ -1,48 +0,0 @@
|
|||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Configuration for YouCompleteMe Vim plugin
|
|
||||||
#
|
|
||||||
# http://valloric.github.io/YouCompleteMe/
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
from os.path import realpath, dirname
|
|
||||||
|
|
||||||
basedir = dirname(realpath(__file__))
|
|
||||||
|
|
||||||
# some default flags
|
|
||||||
# for more information install clang-3.2-doc package and
|
|
||||||
# check UsersManual.html
|
|
||||||
flags = [
|
|
||||||
'-Werror',
|
|
||||||
'-Wall',
|
|
||||||
'-Wextra',
|
|
||||||
'-pedantic',
|
|
||||||
'-Wno-return-type',
|
|
||||||
'-Wno-unused-parameter',
|
|
||||||
'-Wno-unused-variable',
|
|
||||||
|
|
||||||
'-std=c++11',
|
|
||||||
|
|
||||||
# '-x' and 'c++' also required
|
|
||||||
# use 'c' for C projects
|
|
||||||
'-x',
|
|
||||||
'c++',
|
|
||||||
|
|
||||||
# libosmium include dirs
|
|
||||||
'-I%s/include' % basedir,
|
|
||||||
'-I%s/test/include' % basedir,
|
|
||||||
'-I%s/test/data-test/include' % basedir,
|
|
||||||
|
|
||||||
# include third party libraries
|
|
||||||
'-I/usr/include/gdal',
|
|
||||||
]
|
|
||||||
|
|
||||||
# youcompleteme is calling this function to get flags
|
|
||||||
# You can also set database for flags. Check: JSONCompilationDatabase.html in
|
|
||||||
# clang-3.2-doc package
|
|
||||||
def FlagsForFile( filename ):
|
|
||||||
return {
|
|
||||||
'flags': flags,
|
|
||||||
'do_cache': True
|
|
||||||
}
|
|
275
third_party/libosmium/CHANGELOG.md
vendored
275
third_party/libosmium/CHANGELOG.md
vendored
@ -1,275 +0,0 @@
|
|||||||
|
|
||||||
# Change Log
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
|
||||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
|
||||||
|
|
||||||
## [unreleased] -
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
|
|
||||||
## [2.6.0] - 2016-02-04
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- The new handler osmium::handler::CheckOrder can be used to check that a
|
|
||||||
file is properly ordered.
|
|
||||||
- Add new method to build OSM nodes, ways, relations, changesets, and areas
|
|
||||||
in buffers that wraps the older Builder classes. The new code is much easier
|
|
||||||
to use and very flexible. There is no documentation yet, but the tests in
|
|
||||||
`test/t/builder/test_attr.cpp` can give you an idea how it works.
|
|
||||||
- Add util class to get memory usage of current process on Linux.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- New Buffer memory management speeds up Buffer use, because it doesn't clear
|
|
||||||
the memory unnecessarily.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- osmium::Box::extend() function now ignores invalid locations.
|
|
||||||
- Install of external library headers.
|
|
||||||
- Check way has at least one node before calling `is_closed()` in area
|
|
||||||
assembler.
|
|
||||||
- Declaration/definition of some friend functions was in the wrong namespace.
|
|
||||||
|
|
||||||
|
|
||||||
## [2.5.4] - 2015-12-03
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Included gdalcpp.hpp header was updated to version 1.1.1.
|
|
||||||
- Included protozero library was updated to version 1.2.3.
|
|
||||||
- Workarounds for missing constexpr support in Visual Studio removed. All
|
|
||||||
constexpr features we need are supported now.
|
|
||||||
- Some code cleanup after running clang-tidy on the code.
|
|
||||||
- Re-added `Buffer::value_type` typedef. Turns out it is needed when using
|
|
||||||
`std::back_inserter` on the Buffer.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Bugs with Timestamp code on 32 bit platforms. This necessitated
|
|
||||||
some changes in Timestamp which might lead to changes in user
|
|
||||||
code.
|
|
||||||
- Bug in segment intersection code (which appeared on i686 platform).
|
|
||||||
|
|
||||||
|
|
||||||
## [2.5.3] - 2015-11-17
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- `osmium::make_diff_iterator()` helper function.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Deprecated `osmium::Buffer::set_full_callback()`.
|
|
||||||
- Removed DataFile class which was never used anywhere.
|
|
||||||
- Removed unused and obscure `Buffer::value_type` typedef.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Possible overrun in Buffer when using the full-callback.
|
|
||||||
- Incorrect swapping of Buffer.
|
|
||||||
|
|
||||||
|
|
||||||
## [2.5.2] - 2015-11-06
|
|
||||||
|
|
||||||
# Fixed
|
|
||||||
|
|
||||||
- Writing data through an OutputIterator was extremly slow due to
|
|
||||||
lock contention.
|
|
||||||
|
|
||||||
|
|
||||||
## [2.5.1] - 2015-11-05
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Header `osmium/fwd.hpp` with forward declarations of the most commonly
|
|
||||||
used Osmium classes.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Moved `osmium/io/overwrite.hpp` to `osmium/io/writer_options.hpp`
|
|
||||||
If you still include the old file, you'll get a warning.
|
|
||||||
|
|
||||||
|
|
||||||
## [2.5.0] - 2015-11-04
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Helper functions to make input iterator ranges and output iterators.
|
|
||||||
- Add support for reading o5m and o5c files.
|
|
||||||
- Option for osmium::io::Writer to fsync file after writing.
|
|
||||||
- Lots of internal asserts() and other robustness checks.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Updated included protozero library to version 1.2.0.
|
|
||||||
- Complete overhaul of the I/O system making it much more robust against
|
|
||||||
wrong data and failures during I/O operations.
|
|
||||||
- Speed up PBF writing by running parts of it in parallel.
|
|
||||||
- OutputIterator doesn't hold an internal buffer any more, but it uses
|
|
||||||
one in Writer. Calling flush() on the OutputIterator isn't needed any
|
|
||||||
more.
|
|
||||||
- Reader now throws when trying to read after eof or an error.
|
|
||||||
- I/O functions that used to throw std::runtime_error now throw
|
|
||||||
osmium::io_error or derived.
|
|
||||||
- Optional parameters on osmium::io::Writer now work in any order.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- PBF reader now decodes locations of invisible nodes properly.
|
|
||||||
- Invalid Delta encode iterator dereference.
|
|
||||||
- Lots of includes fixed to include (only) what's used.
|
|
||||||
- Dangling reference in area assembly code.
|
|
||||||
|
|
||||||
|
|
||||||
## [2.4.1] - 2015-08-29
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- CRC calculation of tags and changesets.
|
|
||||||
|
|
||||||
|
|
||||||
## [2.4.0] - 2015-08-29
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Checks that user names, member roles and tag keys and values are not longer
|
|
||||||
than 256 * 4 bytes. That is the maximum length 256 Unicode characters
|
|
||||||
can have in UTF-8 encoding.
|
|
||||||
- Support for GDAL 2. GDAL 1 still works.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Improved CMake build scripts.
|
|
||||||
- Updated internal version of Protozero to 1.1.0.
|
|
||||||
- Removed `toogr*` examples. They are in their own repository now.
|
|
||||||
See https://github.com/osmcode/osm-gis-export.
|
|
||||||
- Files about to be memory-mapped (for instance index files) are now set
|
|
||||||
to binary mode on Windows so the application doesn't have to do this.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Hanging program when trying to open file with an unknown file format.
|
|
||||||
- Building problems with old boost versions.
|
|
||||||
- Initialization errors in PBF writer.
|
|
||||||
- Bug in byte swap code.
|
|
||||||
- Output on Windows now always uses binary mode, even when writing to
|
|
||||||
stdout, so OSM xml and opl files always use LF line endings.
|
|
||||||
|
|
||||||
|
|
||||||
## [2.3.0] - 2015-08-18
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Allow instantiating osmium::geom::GEOSFactory with existing GEOS factory.
|
|
||||||
- Low-level functions to support generating a architecture- and endian-
|
|
||||||
independant CRC from OSM data. This is intended to be uses with boost::crc.
|
|
||||||
- Add new debug output format. This format is not intended to be read
|
|
||||||
automatically, but for human consumption. It formats the data nicely.
|
|
||||||
- Make writing of metadata configurable for XML and OPL output (use
|
|
||||||
`add_metadata=false` as file option).
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Changed `add_user()` and `add_role()` in builders to use string length
|
|
||||||
without the 0-termination.
|
|
||||||
- Improved code setting file format from suffix/format argument.
|
|
||||||
- Memory mapping utility class now supports readonly, private writable or
|
|
||||||
shared writable operation.
|
|
||||||
- Allow empty version (0) in PBF files.
|
|
||||||
- Use utf8cpp header-only lib instead of boost for utf8 decoding. The library
|
|
||||||
is included in the libosmium distribution.
|
|
||||||
- New PBF reader and writer based on the protozero. A complete rewrite of the
|
|
||||||
code for reading and writing OSM PBF files. It doesn't use the Google
|
|
||||||
protobuf library and it doesn't use the OSMPBF/OSM-Binary library any more.
|
|
||||||
Instead is uses the protozero lightweight protobuf header library which is
|
|
||||||
included in the code. Not only does the new code have less dependencies, it
|
|
||||||
is faster and more robust. https://github.com/mapbox/protozero
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Various smaller bug fixes.
|
|
||||||
- Add encoding for relation member roles in OPL format.
|
|
||||||
- Change character encoding to new format in OPL: variable length hex code
|
|
||||||
between % characters instead of a % followed by 4-digit hex code. This is
|
|
||||||
necessary because unicode characters can be longer than the 4-digit hex
|
|
||||||
code.
|
|
||||||
- XML writer: The linefeed, carriage return, and tab characters are now
|
|
||||||
escaped properly.
|
|
||||||
- Reading large XML files could block.
|
|
||||||
|
|
||||||
## [2.2.0] - 2015-07-04
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Conversion functions for some low-level types.
|
|
||||||
- BoolVector index class.
|
|
||||||
- `min_op`/`max_op` utility functions.
|
|
||||||
- More tests here and there.
|
|
||||||
- Helper methods `is_between()` and `is_visible_at()` to DiffObject.
|
|
||||||
- GeoJSON factory using the RapidJSON library.
|
|
||||||
- Support for tile calculations.
|
|
||||||
- Create simple polygons from ways in geom factories.
|
|
||||||
- `MemoryMapping` and `TypedMemoryMapping` helper classes.
|
|
||||||
- `close()` function to `mmap_vector_base` class.
|
|
||||||
- Function on `Buffer` class to get iterator to specific offset.
|
|
||||||
- Explicit cast operator from `osmium::Timestamp` to `uint32_t`.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Throw exception on illegal values in functions parsing strings to get ids,
|
|
||||||
versions, etc.
|
|
||||||
- Improved error message for geometry exceptions.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Throw exception from `dump_as_array()` and `dump_as_list()` functions if not
|
|
||||||
implemented in an index.
|
|
||||||
- After writing OSM files, program could stall up to a second.
|
|
||||||
- Dense location store was written out only partially.
|
|
||||||
- Use `uint64_t` as counter in benchmarks, so there can be no overflows.
|
|
||||||
- Example programs now read packed XML files, too.
|
|
||||||
- Refactoring of memory mapping code. Removes leak on Windows.
|
|
||||||
- Better check for invalid locations.
|
|
||||||
- Mark `cbegin()` and `cend()` of `mmap_vector_base` as const functions.
|
|
||||||
|
|
||||||
## [2.1.0] - 2015-03-31
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- When writing PBF files, sorting the PBF stringtables is now optional.
|
|
||||||
- More tests and documentation.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Some functions are now declared `noexcept`.
|
|
||||||
- XML parser fails now if the top-level element is not `osm` or `osmChange`.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Race condition in PBF reader.
|
|
||||||
- Multipolygon collector was accessing non-existent NodeRef.
|
|
||||||
- Doxygen documentation wan't showing all classes/functions due to a bug in
|
|
||||||
Doxygen (up to version 1.8.8). This version contains a workaround to fix
|
|
||||||
this.
|
|
||||||
|
|
||||||
[unreleased]: https://github.com/osmcode/libosmium/compare/v2.6.0...HEAD
|
|
||||||
[2.6.0]: https://github.com/osmcode/libosmium/compare/v2.5.4...v2.6.0
|
|
||||||
[2.5.4]: https://github.com/osmcode/libosmium/compare/v2.5.3...v2.5.4
|
|
||||||
[2.5.3]: https://github.com/osmcode/libosmium/compare/v2.5.2...v2.5.3
|
|
||||||
[2.5.2]: https://github.com/osmcode/libosmium/compare/v2.5.1...v2.5.2
|
|
||||||
[2.5.1]: https://github.com/osmcode/libosmium/compare/v2.5.0...v2.5.1
|
|
||||||
[2.5.0]: https://github.com/osmcode/libosmium/compare/v2.4.1...v2.5.0
|
|
||||||
[2.4.1]: https://github.com/osmcode/libosmium/compare/v2.4.0...v2.4.1
|
|
||||||
[2.4.0]: https://github.com/osmcode/libosmium/compare/v2.3.0...v2.4.0
|
|
||||||
[2.3.0]: https://github.com/osmcode/libosmium/compare/v2.2.0...v2.3.0
|
|
||||||
[2.2.0]: https://github.com/osmcode/libosmium/compare/v2.1.0...v2.2.0
|
|
||||||
[2.1.0]: https://github.com/osmcode/libosmium/compare/v2.0.0...v2.1.0
|
|
||||||
|
|
508
third_party/libosmium/CMakeLists.txt
vendored
508
third_party/libosmium/CMakeLists.txt
vendored
@ -1,508 +0,0 @@
|
|||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# CMake Config
|
|
||||||
#
|
|
||||||
# Libosmium
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Project version
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel;Dev;Coverage"
|
|
||||||
CACHE STRING
|
|
||||||
"List of available configuration types"
|
|
||||||
FORCE)
|
|
||||||
|
|
||||||
project(libosmium)
|
|
||||||
|
|
||||||
set(LIBOSMIUM_VERSION_MAJOR 2)
|
|
||||||
set(LIBOSMIUM_VERSION_MINOR 6)
|
|
||||||
set(LIBOSMIUM_VERSION_PATCH 0)
|
|
||||||
|
|
||||||
set(LIBOSMIUM_VERSION
|
|
||||||
"${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}")
|
|
||||||
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Build options
|
|
||||||
#
|
|
||||||
# (Change with -DOPTION=VALUE on cmake command line.)
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Dev")
|
|
||||||
set(dev_build ON)
|
|
||||||
else()
|
|
||||||
set(dev_build OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(BUILD_EXAMPLES "compile example programs" ON)
|
|
||||||
option(BUILD_TESTING "compile unit tests, please run them with ctest" ON)
|
|
||||||
|
|
||||||
option(BUILD_HEADERS "compile every header file on its own" ${dev_build})
|
|
||||||
option(BUILD_BENCHMARKS "compile benchmark programs" ${dev_build})
|
|
||||||
option(BUILD_DATA_TESTS "compile data tests, please run them with ctest" ${dev_build})
|
|
||||||
|
|
||||||
option(INSTALL_GDALCPP "also install gdalcpp headers" OFF)
|
|
||||||
option(INSTALL_PROTOZERO "also install protozero headers" OFF)
|
|
||||||
option(INSTALL_UTFCPP "also install utfcpp headers" OFF)
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Coverage support
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
check_cxx_compiler_flag("-fkeep-inline-functions" HAS_KEEP_INLINE_FUNCTIONS)
|
|
||||||
if(HAS_KEEP_INLINE_FUNCTIONS)
|
|
||||||
set(extra_coverage_flags_ "-fkeep-inline-functions")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_COVERAGE
|
|
||||||
"-g -O0 -fno-inline-functions -fno-inline --coverage ${extra_coverage_flags_}"
|
|
||||||
CACHE STRING "Flags used by the compiler during coverage builds.")
|
|
||||||
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
|
||||||
"--coverage"
|
|
||||||
CACHE STRING "Flags used by the linker during coverage builds.")
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
|
|
||||||
if(BUILD_EXAMPLES OR BUILD_HEADERS OR BUILD_BENCHMARKS OR BUILD_DATA_TESTS)
|
|
||||||
message(WARNING "Coverage builds don't work for anything but the unit tests")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|
||||||
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "llvm-cov-\\1.\\2"
|
|
||||||
gcov_ ${CMAKE_CXX_COMPILER_VERSION})
|
|
||||||
else()
|
|
||||||
set(gcov_ "gcov")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_program(GCOV ${gcov_} DOC "Coverage tool")
|
|
||||||
find_program(GCOVR "gcovr" DOC "Coverage report tool")
|
|
||||||
|
|
||||||
set(coverage_report_dir "${CMAKE_BINARY_DIR}/coverage")
|
|
||||||
file(MAKE_DIRECTORY ${coverage_report_dir})
|
|
||||||
add_custom_target(coverage
|
|
||||||
${GCOVR}
|
|
||||||
${CMAKE_BINARY_DIR}
|
|
||||||
--root=${CMAKE_SOURCE_DIR}
|
|
||||||
--html --html-details
|
|
||||||
#--verbose
|
|
||||||
#--keep
|
|
||||||
'--filter=.*include/osmium.*'
|
|
||||||
--sort-percentage
|
|
||||||
--gcov-executable=${GCOV}
|
|
||||||
--output=${coverage_report_dir}/index.html)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Find external dependencies
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
find_package(Boost 1.38)
|
|
||||||
mark_as_advanced(CLEAR BOOST_ROOT)
|
|
||||||
|
|
||||||
if(Boost_FOUND)
|
|
||||||
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
|
|
||||||
else()
|
|
||||||
set(BOOST_ROOT "NOT FOUND: please choose" CACHE PATH "")
|
|
||||||
message(FATAL_ERROR "PLEASE, specify the directory where the Boost library is installed in BOOST_ROOT")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# set OSMIUM_INCLUDE_DIR so FindOsmium will not set anything different
|
|
||||||
set(OSMIUM_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
|
||||||
|
|
||||||
include_directories(${OSMIUM_INCLUDE_DIR})
|
|
||||||
|
|
||||||
find_package(Osmium COMPONENTS io gdal geos proj sparsehash)
|
|
||||||
|
|
||||||
# The find_package put the directory where it found the libosmium includes
|
|
||||||
# into OSMIUM_INCLUDE_DIRS. We remove it again, because we want to make
|
|
||||||
# sure to use our own include directory already set up above.
|
|
||||||
list(FIND OSMIUM_INCLUDE_DIRS "${OSMIUM_INCLUDE_DIR}" _own_index)
|
|
||||||
list(REMOVE_AT OSMIUM_INCLUDE_DIRS ${_own_index})
|
|
||||||
set(_own_index)
|
|
||||||
|
|
||||||
include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
if(MSVC)
|
|
||||||
find_path(GETOPT_INCLUDE_DIR getopt.h)
|
|
||||||
find_library(GETOPT_LIBRARY NAMES wingetopt)
|
|
||||||
if(GETOPT_INCLUDE_DIR AND GETOPT_LIBRARY)
|
|
||||||
include_directories(SYSTEM ${GETOPT_INCLUDE_DIR})
|
|
||||||
list(APPEND OSMIUM_LIBRARIES ${GETOPT_LIBRARY})
|
|
||||||
else()
|
|
||||||
set(GETOPT_MISSING 1)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Decide which C++ version to use (Minimum/default: C++11).
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
if(NOT MSVC)
|
|
||||||
if(NOT USE_CPP_VERSION)
|
|
||||||
set(USE_CPP_VERSION c++11)
|
|
||||||
endif()
|
|
||||||
message(STATUS "Use C++ version: ${USE_CPP_VERSION}")
|
|
||||||
# following only available from cmake 2.8.12:
|
|
||||||
# add_compile_options(-std=${USE_CPP_VERSION})
|
|
||||||
# so using this instead:
|
|
||||||
add_definitions(-std=${USE_CPP_VERSION})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Compiler and Linker flags
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
if(MSVC)
|
|
||||||
set(USUAL_COMPILE_OPTIONS "/Ox")
|
|
||||||
set(USUAL_LINK_OPTIONS "/debug")
|
|
||||||
else()
|
|
||||||
set(USUAL_COMPILE_OPTIONS "-O3 -g")
|
|
||||||
set(USUAL_LINK_OPTIONS "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
add_definitions(-DWIN32 -D_WIN32 -DMSWIN32 -DBGDWIN32
|
|
||||||
-DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -D_WIN32_IE=0x0600)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_DEV "${USUAL_COMPILE_OPTIONS}"
|
|
||||||
CACHE STRING "Flags used by the compiler during developer builds."
|
|
||||||
FORCE)
|
|
||||||
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_DEV "${USUAL_LINK_OPTIONS}"
|
|
||||||
CACHE STRING "Flags used by the linker during developer builds."
|
|
||||||
FORCE)
|
|
||||||
mark_as_advanced(
|
|
||||||
CMAKE_CXX_FLAGS_DEV
|
|
||||||
CMAKE_EXE_LINKER_FLAGS_DEV
|
|
||||||
)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${USUAL_COMPILE_OPTIONS}"
|
|
||||||
CACHE STRING "Flags used by the compiler during RELWITHDEBINFO builds."
|
|
||||||
FORCE)
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Build Type
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
# In 'Dev' mode: compile with very strict warnings and turn them into errors.
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Dev")
|
|
||||||
if(NOT MSVC)
|
|
||||||
add_definitions(-Werror)
|
|
||||||
endif()
|
|
||||||
add_definitions(${OSMIUM_WARNING_OPTIONS})
|
|
||||||
# add_definitions(${OSMIUM_WARNING_OPTIONS} ${OSMIUM_DRACONIC_CLANG_OPTIONS} -Wno-documentation -Wno-format-nonliteral -Wno-deprecated -Wno-covered-switch-default -Wno-shadow)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Force RelWithDebInfo build type if none was given
|
|
||||||
if(CMAKE_BUILD_TYPE)
|
|
||||||
set(build_type ${CMAKE_BUILD_TYPE})
|
|
||||||
else()
|
|
||||||
set(build_type "RelWithDebInfo")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_BUILD_TYPE ${build_type}
|
|
||||||
CACHE STRING
|
|
||||||
"Choose the type of build, options are: ${CMAKE_CONFIGURATION_TYPES}."
|
|
||||||
FORCE)
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Unit and data tests
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
enable_testing()
|
|
||||||
|
|
||||||
if(BUILD_TESTING OR BUILD_DATA_TESTS)
|
|
||||||
find_program(MEMORYCHECK_COMMAND valgrind)
|
|
||||||
|
|
||||||
set(MEMORYCHECK_COMMAND_OPTIONS
|
|
||||||
"--trace-children=yes --leak-check=full --show-reachable=yes --error-exitcode=1")
|
|
||||||
|
|
||||||
set(MEMORYCHECK_SUPPRESSIONS_FILE "${PROJECT_SOURCE_DIR}/test/valgrind.supp")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_TESTING)
|
|
||||||
add_subdirectory(test)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_DATA_TESTS)
|
|
||||||
add_subdirectory(test/data-tests)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Optional "cppcheck" target that checks C++ code
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
message(STATUS "Looking for cppcheck")
|
|
||||||
find_program(CPPCHECK cppcheck)
|
|
||||||
|
|
||||||
if(CPPCHECK)
|
|
||||||
message(STATUS "Looking for cppcheck - found")
|
|
||||||
set(CPPCHECK_OPTIONS
|
|
||||||
--enable=warning,style,performance,portability,information,missingInclude --force -Uassert)
|
|
||||||
|
|
||||||
# cpp doesn't find system includes for some reason, suppress that report
|
|
||||||
set(CPPCHECK_OPTIONS ${CPPCHECK_OPTIONS} --suppress=missingIncludeSystem)
|
|
||||||
|
|
||||||
file(GLOB_RECURSE ALL_INCLUDES include/osmium/*.hpp)
|
|
||||||
file(GLOB ALL_EXAMPLES examples/*.cpp)
|
|
||||||
file(GLOB ALL_BENCHMARKS benchmarks/*.cpp)
|
|
||||||
file(GLOB ALL_UNIT_TESTS test/t/*/test_*.cpp)
|
|
||||||
file(GLOB ALL_DATA_TESTS test/data-tests/*.cpp)
|
|
||||||
|
|
||||||
if(Osmium_DEBUG)
|
|
||||||
message(STATUS "Checking includes : ${ALL_INCLUDES}")
|
|
||||||
message(STATUS "Checking example code : ${ALL_EXAMPLES}")
|
|
||||||
message(STATUS "Checking benchmarks : ${ALL_BENCHMARKS}")
|
|
||||||
message(STATUS "Checking unit test code: ${ALL_UNIT_TESTS}")
|
|
||||||
message(STATUS "Checking data test code: ${ALL_DATA_TESTS}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CPPCHECK_FILES
|
|
||||||
${ALL_INCLUDES}
|
|
||||||
${ALL_EXAMPLES}
|
|
||||||
${ALL_BENCHMARKS}
|
|
||||||
${ALL_UNIT_TESTS}
|
|
||||||
${ALL_DATA_TESTS})
|
|
||||||
|
|
||||||
add_custom_target(cppcheck
|
|
||||||
${CPPCHECK}
|
|
||||||
--std=c++11 ${CPPCHECK_OPTIONS}
|
|
||||||
-I ${CMAKE_SOURCE_DIR}/include
|
|
||||||
${CPPCHECK_FILES}
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
message(STATUS "Looking for cppcheck - not found")
|
|
||||||
message(STATUS " Build target 'cppcheck' will not be available.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Examples, benchmarks and documentation
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if(BUILD_EXAMPLES)
|
|
||||||
add_subdirectory(examples)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_BENCHMARKS)
|
|
||||||
add_subdirectory(benchmarks)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_subdirectory(doc)
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Headers
|
|
||||||
#
|
|
||||||
# This will try to compile include files on their own to detect missing
|
|
||||||
# include directives and other dependency-related problems. Note that if this
|
|
||||||
# work, it is not enough to be sure it will compile in production code.
|
|
||||||
# But if it reports an error we know we are missing something.
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
if(BUILD_HEADERS)
|
|
||||||
file(GLOB_RECURSE
|
|
||||||
ALL_HPPS
|
|
||||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/include"
|
|
||||||
include/osmium/*.hpp)
|
|
||||||
|
|
||||||
file(MAKE_DIRECTORY header_check)
|
|
||||||
|
|
||||||
foreach(hpp ${ALL_HPPS})
|
|
||||||
string(REPLACE ".hpp" "" tmp ${hpp})
|
|
||||||
string(REPLACE "/" "__" libname ${tmp})
|
|
||||||
|
|
||||||
# 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}>\n")
|
|
||||||
|
|
||||||
# There is no way in CMake to just compile but not link a C++ file,
|
|
||||||
# so we pretend to build a library here.
|
|
||||||
add_library(${libname} STATIC ${DUMMYCPP} include/${hpp})
|
|
||||||
|
|
||||||
#### this is better but only supported from cmake 3.0:
|
|
||||||
###add_library(${libname} OBJECT ${DUMMYCPP} include/${hpp})
|
|
||||||
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Optional "clang-tidy" target
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
message(STATUS "Looking for clang-tidy")
|
|
||||||
find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-3.9 clang-tidy-3.8 clang-tidy-3.7 clang-tidy-3.6 clang-tidy-3.5)
|
|
||||||
|
|
||||||
if(CLANG_TIDY)
|
|
||||||
message(STATUS "Looking for clang-tidy - found")
|
|
||||||
|
|
||||||
if(BUILD_EXAMPLES)
|
|
||||||
file(GLOB CT_ALL_EXAMPLES examples/*.cpp)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_TESTING)
|
|
||||||
file(GLOB CT_ALL_UNIT_TESTS test/t/*/test_*.cpp)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_HEADERS)
|
|
||||||
file(GLOB_RECURSE CT_ALL_INCLUDES ${CMAKE_BINARY_DIR}/header_check/osmium__*.cpp)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_BENCHMARKS)
|
|
||||||
file(GLOB CT_ALL_BENCHMARKS benchmarks/*.cpp)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_DATA_TESTS)
|
|
||||||
file(GLOB CT_ALL_DATA_TESTS test/data-tests/*.cpp)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(Osmium_DEBUG)
|
|
||||||
message(STATUS "Checking example code : ${CT_ALL_EXAMPLES}")
|
|
||||||
message(STATUS "Checking unit test code: ${CT_ALL_UNIT_TESTS}")
|
|
||||||
message(STATUS "Checking includes : ${CT_ALL_INCLUDES}")
|
|
||||||
message(STATUS "Checking benchmarks : ${CT_ALL_BENCHMARKS}")
|
|
||||||
message(STATUS "Checking data test code: ${CT_ALL_DATA_TESTS}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CT_CHECK_FILES
|
|
||||||
${CT_ALL_EXAMPLES}
|
|
||||||
${CT_ALL_UNIT_TESTS}
|
|
||||||
${CT_ALL_INCLUDES}
|
|
||||||
${CT_ALL_BENCHMARKS}
|
|
||||||
${CT_ALL_DATA_TESTS})
|
|
||||||
|
|
||||||
# For a list of check options, see:
|
|
||||||
# http://clang.llvm.org/extra/clang-tidy/checks/list.html
|
|
||||||
|
|
||||||
list(APPEND CT_CHECKS "cert-*"
|
|
||||||
"-cert-err60-cpp") # even the std lib doesn't do this
|
|
||||||
|
|
||||||
# disabled, because it is slow
|
|
||||||
# list(APPEND CT_CHECKS "clang-analyzer-*")
|
|
||||||
|
|
||||||
list(APPEND CT_CHECKS "google-*"
|
|
||||||
"-google-explicit-constructor"
|
|
||||||
"-google-readability-casting"
|
|
||||||
"-google-readability-function")
|
|
||||||
|
|
||||||
list(APPEND CT_CHECKS "llvm-*"
|
|
||||||
"-llvm-include-order")
|
|
||||||
|
|
||||||
list(APPEND CT_CHECKS "misc-*"
|
|
||||||
"-misc-argument-comment")
|
|
||||||
|
|
||||||
list(APPEND CT_CHECKS "modernize-*")
|
|
||||||
|
|
||||||
list(APPEND CT_CHECKS "readability-*"
|
|
||||||
"-readability-identifier-naming"
|
|
||||||
"-readability-named-parameter")
|
|
||||||
|
|
||||||
string(REPLACE ";" "," ALL_CHECKS "${CT_CHECKS}")
|
|
||||||
|
|
||||||
add_custom_target(clang-tidy
|
|
||||||
${CLANG_TIDY}
|
|
||||||
-p ${CMAKE_BINARY_DIR}
|
|
||||||
-header-filter='include/osmium/.*'
|
|
||||||
-checks="${ALL_CHECKS}"
|
|
||||||
${CT_CHECK_FILES}
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
message(STATUS "Looking for clang-tidy - not found")
|
|
||||||
message(STATUS " Build target 'clang-tidy' will not be available.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Installation
|
|
||||||
#
|
|
||||||
# External libraries are only installed if the options are set in case they
|
|
||||||
# are installed from somewhere else.
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
install(DIRECTORY include/osmium DESTINATION include)
|
|
||||||
|
|
||||||
if(INSTALL_GDALCPP)
|
|
||||||
install(FILES include/gdalcpp.hpp DESTINATION include)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(INSTALL_PROTOZERO)
|
|
||||||
install(DIRECTORY include/protozero DESTINATION include)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(INSTALL_UTFCPP)
|
|
||||||
install(FILES include/utf8.h DESTINATION include)
|
|
||||||
install(DIRECTORY include/utf8 DESTINATION include)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Packaging
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR ${LIBOSMIUM_VERSION_MAJOR})
|
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR ${LIBOSMIUM_VERSION_MINOR})
|
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH ${LIBOSMIUM_VERSION_PATCH})
|
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
set(CPACK_GENERATOR ZIP)
|
|
||||||
else()
|
|
||||||
set(CPACK_GENERATOR TGZ)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(CPack)
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Print warnings at the end
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
if(BUILD_DATA_TESTS AND OSM_TESTDATA STREQUAL "OSM_TESTDATA-NOTFOUND")
|
|
||||||
message("\n========================== WARNING ==========================")
|
|
||||||
message("osm-testdata directory not found, data tests were disabled!\n")
|
|
||||||
message("You can get it from https://github.com/osmcode/osm-testdata")
|
|
||||||
message("Clone it into the same directory libosmium is in")
|
|
||||||
message("or set the OSM_TESTDATA cmake variable to its path.")
|
|
||||||
message("=============================================================\n")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
143
third_party/libosmium/CONTRIBUTING.md
vendored
143
third_party/libosmium/CONTRIBUTING.md
vendored
@ -1,143 +0,0 @@
|
|||||||
|
|
||||||
# Notes for Developers
|
|
||||||
|
|
||||||
Read this if you want to contribute to Libosmium.
|
|
||||||
|
|
||||||
|
|
||||||
## Versioning
|
|
||||||
|
|
||||||
Osmium is currently considered in beta and doesn't use versioning yet. Proper
|
|
||||||
versions will be introduced as soon as it is somewhat stable.
|
|
||||||
|
|
||||||
|
|
||||||
## Namespace
|
|
||||||
|
|
||||||
All Osmium code MUST be in the `osmium` namespace or one of its sub-namespaces.
|
|
||||||
|
|
||||||
|
|
||||||
## Include-Only
|
|
||||||
|
|
||||||
Osmium is a include-only library. You can't compile the library itself. There
|
|
||||||
is no libosmium.so.
|
|
||||||
|
|
||||||
One drawback ist that you can't have static data in classes, because there
|
|
||||||
is no place to put this data.
|
|
||||||
|
|
||||||
All free functions must be declared `inline`.
|
|
||||||
|
|
||||||
|
|
||||||
## Coding Conventions
|
|
||||||
|
|
||||||
These coding conventions have been changing over time and some code is still
|
|
||||||
different.
|
|
||||||
|
|
||||||
* All include files have `#ifdef` guards around them, macros are the path name
|
|
||||||
in all uppercase where the slashes (`/`) have been changed to underscore (`_`).
|
|
||||||
* Class names begin with uppercase chars and use CamelCase. Smaller helper
|
|
||||||
classes are usually defined as struct and have lowercase names.
|
|
||||||
* Macros (and only macros) are all uppercase. Use macros sparingly, usually
|
|
||||||
a simple (maybe constexpr) inline function is better. Undef macros after use
|
|
||||||
if possible.
|
|
||||||
* Macros should only be used for controlling which parts of the code should be
|
|
||||||
included when compiling or to avoid major code repetitions.
|
|
||||||
* Variables, attributes, and function names are lowercase with
|
|
||||||
`underscores_between_words`.
|
|
||||||
* Class attribute names start with `m_` (member).
|
|
||||||
* Use `descriptive_variable_names`, exceptions are well-established conventions
|
|
||||||
like `i` for a loop variable. Iterators are usually called `it`.
|
|
||||||
* Declare variables where they are first used (C++ style), not at the beginning
|
|
||||||
of a function (old C style).
|
|
||||||
* Names from external namespaces (even `std`) are always mentioned explicitly.
|
|
||||||
Do not use `using` (except for `std::swap`). This way we can't even by
|
|
||||||
accident pollute the namespace of the code using Osmium.
|
|
||||||
* Always use the standard swap idiom: `using std::swap; swap(foo, bar);`.
|
|
||||||
* `#include` directives appear in three "blocks" after the copyright notice.
|
|
||||||
The blocks are separated by blank lines. First block contains `#include`s for
|
|
||||||
standard C/C++ includes, second block for any external libs used, third
|
|
||||||
block for osmium internal includes. Within each block `#include`s are usually
|
|
||||||
sorted by path name. All `#include`s use `<>` syntax not `""`.
|
|
||||||
* Names not to be used from outside the library should be in a namespace
|
|
||||||
called `detail` under the namespace where they would otherwise appear. If
|
|
||||||
whole include files are never meant to be included from outside they should
|
|
||||||
be in a subdirectory called `detail`.
|
|
||||||
* All files have suffix `.hpp`.
|
|
||||||
* Closing } of all classes and namespaces should have a trailing comment
|
|
||||||
with the name of the class/namespace.
|
|
||||||
* All constructors with one (or more arguments if they have a default) should
|
|
||||||
be declared "explicit" unless there is a reason for them not to be. Document
|
|
||||||
that reason.
|
|
||||||
* If a class has any of the special methods (copy/move constructor/assigment,
|
|
||||||
destructor) it should have all of them, possibly marking them as default or
|
|
||||||
deleted.
|
|
||||||
* Typedefs have `names_like_this_type` which end in `_type`. Typedefs should
|
|
||||||
use the new `using foo_type = bar` syntax instead of the old
|
|
||||||
`typedef bar foo_type`.
|
|
||||||
* Template parameters are single uppercase letters or start with uppercase `T`
|
|
||||||
and use CamelCase.
|
|
||||||
* Always use `typename` in templates, not `class`: `template <typename T>`.
|
|
||||||
* The ellipsis in variadic template never has a space to the left of it and
|
|
||||||
always has a space to the right: `template <typename... TArgs>` etc.
|
|
||||||
|
|
||||||
Keep to the indentation and other styles used in the code. Use `make indent`
|
|
||||||
in the toplevel directory to fix indentation and styling. It calls `astyle`
|
|
||||||
with the right parameters. This program is in the `astyle` Debian package.
|
|
||||||
|
|
||||||
|
|
||||||
## C++11
|
|
||||||
|
|
||||||
Osmium uses C++11 and you can use its features such as auto, lambdas,
|
|
||||||
threading, etc. There are a few features we do not use, because even modern
|
|
||||||
compilers don't support them yet. This list might change as we get more data
|
|
||||||
about which compilers support which feature and what operating system versions
|
|
||||||
or distributions have which versions of these compilers installed.
|
|
||||||
|
|
||||||
GCC 4.6 - too old, not supported (Ubuntu 12.04 LTS)
|
|
||||||
GCC 4.7.2 - can probably not be supported (Debian wheezy)
|
|
||||||
GCC 4.7.3 - probably works
|
|
||||||
GCC 4.8 - works and is supported from here on
|
|
||||||
clang 3.0 - too old, not supported (Debian wheezy, Ubuntu 12.04 LTS)
|
|
||||||
clang 3.2 - probably works
|
|
||||||
clang 3.5 - works and is supported from here on
|
|
||||||
|
|
||||||
Use `include/osmium/util/compatibility.hpp` if there are compatibility problems
|
|
||||||
between compilers due to different C++11 support.
|
|
||||||
|
|
||||||
|
|
||||||
## Checking your code
|
|
||||||
|
|
||||||
The Osmium makefiles use pretty draconian warning options for the compiler.
|
|
||||||
This is good. Code MUST never produce any warnings, even with those settings.
|
|
||||||
If absolutely necessary pragmas can be used to disable certain warnings in
|
|
||||||
specific areas of the code.
|
|
||||||
|
|
||||||
If the static code checker `cppcheck` is installed, the CMake configuration
|
|
||||||
will add a new build target `cppcheck` that will check all `.cpp` and `.hpp`
|
|
||||||
files. Cppcheck finds some bugs that gcc/clang doesn't. But take the result
|
|
||||||
with a grain of salt, it also sometimes produces wrong warnings.
|
|
||||||
|
|
||||||
Set `BUILD_HEADERS=ON` in the CMake config to enable compiling all include
|
|
||||||
files on their own to check whether dependencies are all okay. All include
|
|
||||||
files MUST include all other include files they depend on.
|
|
||||||
|
|
||||||
Call `cmake/iwyu.sh` to check for proper includes and forward declarations.
|
|
||||||
This uses the clang-based `include-what-you-use` program. Note that it does
|
|
||||||
produce some false reports and crashes often. The `osmium.imp` file can be
|
|
||||||
used to define mappings for iwyu. See the IWYU tool at
|
|
||||||
<http://code.google.com/p/include-what-you-use/>.
|
|
||||||
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
There are a unit tests using the Catch Unit Test Framework in the `test`
|
|
||||||
directory and some data tests in `test/osm-testdata`. They are built by the
|
|
||||||
default cmake config. Run `ctest` to run them. Many more tests are needed.
|
|
||||||
|
|
||||||
|
|
||||||
## Documenting the code
|
|
||||||
|
|
||||||
All namespaces, classes, functions, attributes, etc. should be documented.
|
|
||||||
|
|
||||||
Osmium uses the Doxygen (www.doxygen.org) source code documentation system.
|
|
||||||
If it is installed, the CMake configuration will add a new build target, so
|
|
||||||
you can build it with `make doc`.
|
|
||||||
|
|
233
third_party/libosmium/EXTERNAL_LICENSES.txt
vendored
233
third_party/libosmium/EXTERNAL_LICENSES.txt
vendored
@ -1,233 +0,0 @@
|
|||||||
|
|
||||||
==== For protozero from https://github.com/mapbox/protozero
|
|
||||||
|
|
||||||
protozero copyright (c) Mapbox.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in
|
|
||||||
the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
|
||||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
||||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
==== For protozero from https://github.com/mapbox/protozero
|
|
||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
==== 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.
|
|
||||||
|
|
23
third_party/libosmium/LICENSE.txt
vendored
23
third_party/libosmium/LICENSE.txt
vendored
@ -1,23 +0,0 @@
|
|||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
25
third_party/libosmium/Makefile
vendored
25
third_party/libosmium/Makefile
vendored
@ -1,25 +0,0 @@
|
|||||||
|
|
||||||
all:
|
|
||||||
mkdir -p build && cd build && cmake .. && $(MAKE)
|
|
||||||
|
|
||||||
doc:
|
|
||||||
mkdir -p build && cd build && cmake .. && $(MAKE) doc
|
|
||||||
|
|
||||||
clean:
|
|
||||||
if test -d build; then cd build && $(MAKE) clean; fi
|
|
||||||
|
|
||||||
distclean:
|
|
||||||
rm -fr build
|
|
||||||
|
|
||||||
#deb:
|
|
||||||
# debuild -I -us -uc
|
|
||||||
#
|
|
||||||
#deb-clean:
|
|
||||||
# debuild clean
|
|
||||||
|
|
||||||
indent:
|
|
||||||
astyle --style=java --indent-namespaces --indent-switches --pad-header --lineend=linux --suffix=none --recursive include/\*.hpp examples/\*.cpp test/\*.cpp
|
|
||||||
# astyle --style=java --indent-namespaces --indent-switches --pad-header --unpad-paren --align-pointer=type --lineend=linux --suffix=none --recursive include/\*.hpp examples/\*.cpp test/\*.cpp
|
|
||||||
|
|
||||||
.PHONY: clean distclean deb deb-clean doc indent
|
|
||||||
|
|
114
third_party/libosmium/README.md
vendored
114
third_party/libosmium/README.md
vendored
@ -1,114 +0,0 @@
|
|||||||
# Libosmium
|
|
||||||
|
|
||||||
http://osmcode.org/libosmium
|
|
||||||
|
|
||||||
A fast and flexible C++ library for working with OpenStreetMap data.
|
|
||||||
|
|
||||||
[](https://travis-ci.org/osmcode/libosmium)
|
|
||||||
[](https://ci.appveyor.com/project/Mapbox/libosmium)
|
|
||||||
|
|
||||||
Libosmium is developed on Linux, but also works on OSX and Windows (with some
|
|
||||||
limitations).
|
|
||||||
|
|
||||||
There are a few applications that use the Osmium library in the examples
|
|
||||||
directory. See the [osmium-contrib](http://github.com/osmcode/osmium-contrib)
|
|
||||||
repository for more example code.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
Because Libosmium uses many C++11 features you need a modern compiler and
|
|
||||||
standard C++ library. Osmium needs at least GCC 4.8 or clang (LLVM) 3.4.
|
|
||||||
(Some parts may work with older versions.)
|
|
||||||
|
|
||||||
Different parts of Libosmium (and the applications built on top of it) need
|
|
||||||
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](https://github.com/osmcode/libosmium/wiki/Libosmium-dependencies).
|
|
||||||
|
|
||||||
The following external (header-only) libraries are included in the libosmium
|
|
||||||
repository:
|
|
||||||
* [gdalcpp](https://github.com/joto/gdalcpp)
|
|
||||||
* [protozero](https://github.com/mapbox/protozero)
|
|
||||||
* [utfcpp](http://utfcpp.sourceforge.net/)
|
|
||||||
|
|
||||||
If you want (some of) those libraries to be installed along with libosmium
|
|
||||||
itself when calling `make install`, you have to use the CMake options
|
|
||||||
`INSTALL_GDALCPP`, `INSTALL_PROTOZERO`, and/or `INSTALL_UTFCPP`.
|
|
||||||
|
|
||||||
|
|
||||||
## Directories
|
|
||||||
|
|
||||||
* benchmarks: Some benchmarks checking different parts of Libosmium.
|
|
||||||
|
|
||||||
* cmake: CMake configuration scripts.
|
|
||||||
|
|
||||||
* doc: Config for documentation.
|
|
||||||
|
|
||||||
* examples: Osmium example applications.
|
|
||||||
|
|
||||||
* include: C/C++ include files. All of Libosmium is in those header files
|
|
||||||
which are needed for building Osmium applications.
|
|
||||||
|
|
||||||
* test: Tests (see below).
|
|
||||||
|
|
||||||
|
|
||||||
## Building
|
|
||||||
|
|
||||||
Osmium is a header-only library, so there is nothing to build for the
|
|
||||||
library itself.
|
|
||||||
|
|
||||||
But there are some tests and examples that can be build. Libosmium uses
|
|
||||||
cmake:
|
|
||||||
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake ..
|
|
||||||
make
|
|
||||||
|
|
||||||
This will build the examples and tests. Call `ctest` to run the tests.
|
|
||||||
|
|
||||||
For more see the
|
|
||||||
[Libosmium Wiki](https://github.com/osmcode/libosmium/wiki/Building-Libosmium).
|
|
||||||
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
See the
|
|
||||||
[Libosmium Wiki](https://github.com/osmcode/libosmium/wiki/Testing-Libosmium)
|
|
||||||
for instructions.
|
|
||||||
|
|
||||||
|
|
||||||
## Osmium on 32bit Machines
|
|
||||||
|
|
||||||
Osmium works well on 64 bit machines, but on 32 bit machines there are some
|
|
||||||
problems. Be aware that not everything will work on 32 bit architectures.
|
|
||||||
This is mostly due to the 64 bit needed for node IDs. Also Osmium hasn't been
|
|
||||||
tested well on 32 bit systems. Here are some issues you might run into:
|
|
||||||
|
|
||||||
* Google Sparsehash does not work on 32 bit machines in our use case.
|
|
||||||
* The `mmap` system call is called with a `size_t` argument, so it can't
|
|
||||||
give you more than 4GByte of memory on 32 bit systems. This might be a
|
|
||||||
problem.
|
|
||||||
|
|
||||||
Please report any issues you have and we might be able to solve them.
|
|
||||||
|
|
||||||
|
|
||||||
## Switching from the old Osmium
|
|
||||||
|
|
||||||
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](https://github.com/osmcode/libosmium/wiki/Changes-from-old-versions-of-Osmium).
|
|
||||||
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Libosmium is available under the Boost Software License. See LICENSE.txt.
|
|
||||||
|
|
||||||
|
|
||||||
## Authors
|
|
||||||
|
|
||||||
Libosmium was mainly written and is maintained by Jochen Topf
|
|
||||||
(jochen@topf.org). See the git commit log for other authors.
|
|
||||||
|
|
109
third_party/libosmium/appveyor.yml
vendored
109
third_party/libosmium/appveyor.yml
vendored
@ -1,109 +0,0 @@
|
|||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Configuration for continuous integration service at appveyor.com
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
environment:
|
|
||||||
matrix:
|
|
||||||
- config: Dev
|
|
||||||
- config: RelWithDebInfo
|
|
||||||
|
|
||||||
shallow_clone: true
|
|
||||||
|
|
||||||
# Operating system (build VM template)
|
|
||||||
os: Visual Studio 2015
|
|
||||||
|
|
||||||
# scripts that are called at very beginning, before repo cloning
|
|
||||||
init:
|
|
||||||
|
|
||||||
# clone directory
|
|
||||||
clone_folder: c:\projects\libosmium
|
|
||||||
|
|
||||||
platform: x64
|
|
||||||
|
|
||||||
install:
|
|
||||||
# show all available env vars
|
|
||||||
- set
|
|
||||||
- echo cmake on AppVeyor
|
|
||||||
- cmake -version
|
|
||||||
- call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
|
|
||||||
- set PATH=c:\projects\libosmium\cmake-3.1.0-win32-x86\bin;%PATH%
|
|
||||||
- set LODEPSDIR=c:\projects\libosmium\libosmium-deps
|
|
||||||
- set PROJ_LIB=%LODEPSDIR%\proj\share
|
|
||||||
- set GDAL_DATA=%LODEPSDIR%\gdal\data
|
|
||||||
#geos.dll
|
|
||||||
- set PATH=%LODEPSDIR%\geos\lib;%PATH%
|
|
||||||
#gdal.dll
|
|
||||||
- set PATH=%LODEPSDIR%\gdal\lib;%PATH%
|
|
||||||
#libexpat.dll
|
|
||||||
- set PATH=%LODEPSDIR%\expat\lib;%PATH%
|
|
||||||
#libtiff.dll
|
|
||||||
- set PATH=%LODEPSDIR%\libtiff\lib;%PATH%
|
|
||||||
#jpeg.dll
|
|
||||||
- set PATH=%LODEPSDIR%\jpeg\lib;%PATH%
|
|
||||||
#zlibwapi.dll
|
|
||||||
- set PATH=%LODEPSDIR%\zlib\lib;%PATH%
|
|
||||||
#convert backslashes in bzip2 path to forward slashes
|
|
||||||
#cmake cannot find it otherwise
|
|
||||||
- set LIBBZIP2=%LODEPSDIR%\bzip2\lib\libbz2.lib
|
|
||||||
- set LIBBZIP2=%LIBBZIP2:\=/%
|
|
||||||
- ps: Start-FileDownload https://mapbox.s3.amazonaws.com/windows-builds/windows-build-deps/cmake-3.1.0-win32-x86.7z -FileName cm.7z
|
|
||||||
- ps: Start-FileDownload https://mapbox.s3.amazonaws.com/windows-builds/windows-build-deps/libosmium-deps-win-14.0-x64.7z -FileName lodeps.7z
|
|
||||||
- 7z x cm.7z | %windir%\system32\find "ing archive"
|
|
||||||
- 7z x lodeps.7z | %windir%\system32\find "ing archive"
|
|
||||||
- echo %LODEPSDIR%
|
|
||||||
- dir %LODEPSDIR%
|
|
||||||
- echo our own cmake
|
|
||||||
- cmake -version
|
|
||||||
- cd c:\projects
|
|
||||||
- git clone --depth 1 https://github.com/osmcode/osm-testdata.git
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
- cd c:\projects\libosmium
|
|
||||||
- mkdir build
|
|
||||||
- cd build
|
|
||||||
- echo %config%
|
|
||||||
# This will produce lots of LNK4099 warnings which can be ignored.
|
|
||||||
# Unfortunately they can't be disabled, see
|
|
||||||
# http://stackoverflow.com/questions/661606/visual-c-how-to-disable-specific-linker-warnings
|
|
||||||
- cmake -LA -G "Visual Studio 14 Win64"
|
|
||||||
-DOsmium_DEBUG=TRUE
|
|
||||||
-DCMAKE_BUILD_TYPE=%config%
|
|
||||||
-DBUILD_HEADERS=OFF
|
|
||||||
-DBOOST_ROOT=%LODEPSDIR%\boost
|
|
||||||
-DBoost_PROGRAM_OPTIONS_LIBRARY=%LODEPSDIR%\boost\lib\libboost_program_options-vc140-mt-1_58.lib
|
|
||||||
-DZLIB_LIBRARY=%LODEPSDIR%\zlib\lib\zlibwapi.lib
|
|
||||||
-DBZIP2_LIBRARY_RELEASE=%LIBBZIP2%
|
|
||||||
-DCMAKE_PREFIX_PATH=%LODEPSDIR%\zlib;%LODEPSDIR%\expat;%LODEPSDIR%\bzip2;%LODEPSDIR%\geos;%LODEPSDIR%\gdal;%LODEPSDIR%\proj;%LODEPSDIR%\sparsehash;%LODEPSDIR%\wingetopt
|
|
||||||
..
|
|
||||||
- msbuild libosmium.sln /p:Configuration=%config% /toolsversion:14.0 /p:Platform=x64 /p:PlatformToolset=v140
|
|
||||||
#- cmake .. -LA -G "NMake Makefiles"
|
|
||||||
# -DOsmium_DEBUG=TRUE
|
|
||||||
# -DCMAKE_BUILD_TYPE=%config%
|
|
||||||
# -DBOOST_ROOT=%LODEPSDIR%\boost
|
|
||||||
# -DBoost_PROGRAM_OPTIONS_LIBRARY=%LODEPSDIR%\boost\lib\libboost_program_options-vc140-mt-1_57.lib
|
|
||||||
# -DZLIB_LIBRARY=%LODEPSDIR%\zlib\lib\zlibwapi.lib
|
|
||||||
# -DZLIB_INCLUDE_DIR=%LODEPSDIR%\zlib\include
|
|
||||||
# -DEXPAT_LIBRARY=%LODEPSDIR%\expat\lib\libexpat.lib
|
|
||||||
# -DEXPAT_INCLUDE_DIR=%LODEPSDIR%\expat\include
|
|
||||||
# -DBZIP2_LIBRARIES=%LIBBZIP2%
|
|
||||||
# -DBZIP2_INCLUDE_DIR=%LODEPSDIR%\bzip2\include
|
|
||||||
# -DGDAL_LIBRARY=%LODEPSDIR%\gdal\lib\gdal_i.lib
|
|
||||||
# -DGDAL_INCLUDE_DIR=%LODEPSDIR%\gdal\include
|
|
||||||
# -DGEOS_LIBRARY=%LODEPSDIR%\geos\lib\geos.lib
|
|
||||||
# -DGEOS_INCLUDE_DIR=%LODEPSDIR%\geos\include
|
|
||||||
# -DPROJ_LIBRARY=%LODEPSDIR%\proj\lib\proj.lib
|
|
||||||
# -DPROJ_INCLUDE_DIR=%LODEPSDIR%\proj\include
|
|
||||||
# -DSPARSEHASH_INCLUDE_DIR=%LODEPSDIR%\sparsehash\include
|
|
||||||
# -DGETOPT_LIBRARY=%LODEPSDIR%\wingetopt\lib\wingetopt.lib
|
|
||||||
# -DGETOPT_INCLUDE_DIR=%LODEPSDIR%\wingetopt\include
|
|
||||||
#- nmake
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
# "-E testdata-overview" exempts one test we know fails on Appveyor
|
|
||||||
# because we currently don't have spatialite support.
|
|
||||||
- ctest --output-on-failure
|
|
||||||
-C %config%
|
|
||||||
-E testdata-overview
|
|
||||||
|
|
49
third_party/libosmium/benchmarks/CMakeLists.txt
vendored
49
third_party/libosmium/benchmarks/CMakeLists.txt
vendored
@ -1,49 +0,0 @@
|
|||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# CMake Config
|
|
||||||
#
|
|
||||||
# Libosmium benchmarks
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
message(STATUS "Configuring benchmarks")
|
|
||||||
|
|
||||||
set(BENCHMARKS
|
|
||||||
count
|
|
||||||
count_tag
|
|
||||||
index_map
|
|
||||||
static_vs_dynamic_index
|
|
||||||
write_pbf
|
|
||||||
CACHE STRING "Benchmark programs"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Configure benchmarks
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
message(STATUS "Configuring benchmarks - Building these benchmarks:")
|
|
||||||
foreach(benchmark ${BENCHMARKS})
|
|
||||||
message(STATUS " - osmium_benchmark_${benchmark}")
|
|
||||||
add_executable(osmium_benchmark_${benchmark}
|
|
||||||
"osmium_benchmark_${benchmark}.cpp")
|
|
||||||
target_link_libraries(osmium_benchmark_${benchmark}
|
|
||||||
${OSMIUM_IO_LIBRARIES}
|
|
||||||
${BENCHMARK_LIBS_${benchmark}})
|
|
||||||
configure_file(run_benchmark_${benchmark}.sh
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/run_benchmark_${benchmark}.sh
|
|
||||||
@ONLY)
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
foreach(file setup run_benchmarks)
|
|
||||||
configure_file(${file}.sh ${CMAKE_CURRENT_BINARY_DIR}/${file}.sh @ONLY)
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
message(STATUS "Configuring benchmarks - done")
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
41
third_party/libosmium/benchmarks/README.md
vendored
41
third_party/libosmium/benchmarks/README.md
vendored
@ -1,41 +0,0 @@
|
|||||||
|
|
||||||
# Benchmarks
|
|
||||||
|
|
||||||
Benchmarks check the performance of different parts of Libosmium.
|
|
||||||
|
|
||||||
## Preparations
|
|
||||||
|
|
||||||
To run the benchmarks first make a directory for the data files somewhere
|
|
||||||
(outside the repository) and set the `DATA_DIR` environment variable:
|
|
||||||
|
|
||||||
export DATA_DIR=benchmark_data
|
|
||||||
mkdir $DATA_DIR
|
|
||||||
|
|
||||||
Then copy the OSM files you want to do the benchmarks with into this directory.
|
|
||||||
You can use the `download_data.sh` script to download a selection of OSM files
|
|
||||||
in different sizes, but you can use a different selection, too. The benchmarks
|
|
||||||
will use whatever files you have in the `DATA_DIR` directory.
|
|
||||||
|
|
||||||
The download script will start the data files names with a number in order of
|
|
||||||
the size of the file from smallest to largest. You can use the same convention
|
|
||||||
or use a different one. Benchmarks will be run on the files in alphabetical
|
|
||||||
order.
|
|
||||||
|
|
||||||
The files don't have to be in that directory, you can add soft links from that
|
|
||||||
directory to the real file locations if that suits you.
|
|
||||||
|
|
||||||
## Compiling the benchmarks
|
|
||||||
|
|
||||||
To build the benchmarks set the `BUILD_BENCHMARKS` option when configuring with
|
|
||||||
CMake and run the compilation by calling `make` (or whatever build tool you
|
|
||||||
are using).
|
|
||||||
|
|
||||||
## Running the benchmarks
|
|
||||||
|
|
||||||
Go to the build directory and run `benchmarks/run_benchmarks.sh`. You can also
|
|
||||||
run each benchmark on its own by calling the respective script in the
|
|
||||||
`benchmarks` directory.
|
|
||||||
|
|
||||||
Results of the benchmarks will be printed to stdout, you might want to redirect
|
|
||||||
them into a file.
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# download_data.sh
|
|
||||||
#
|
|
||||||
|
|
||||||
cd $DATA_DIR
|
|
||||||
curl --location --output 1_liechtenstein.osm.pbf http://download.geofabrik.de/europe/liechtenstein-latest.osm.pbf # about 1 MB
|
|
||||||
curl --location --output 2_bremen.osm.pbf http://download.geofabrik.de/europe/germany/bremen-latest.osm.pbf # about 13 MB
|
|
||||||
curl --location --output 3_sachsen.osm.pbf http://download.geofabrik.de/europe/germany/sachsen-latest.osm.pbf # about 120 MB
|
|
||||||
curl --location --output 4_germany.osm.pbf http://download.geofabrik.de/europe/germany-latest.osm.pbf # about 2 GB
|
|
||||||
curl --location --output 5_planet.osm.pbf http://planet.osm.org/pbf/planet-latest.osm.pbf # about 26 GB
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
The code in this file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
#include <osmium/handler.hpp>
|
|
||||||
#include <osmium/visitor.hpp>
|
|
||||||
|
|
||||||
struct CountHandler : public osmium::handler::Handler {
|
|
||||||
|
|
||||||
uint64_t nodes = 0;
|
|
||||||
uint64_t ways = 0;
|
|
||||||
uint64_t relations = 0;
|
|
||||||
|
|
||||||
void node(osmium::Node&) {
|
|
||||||
++nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void way(osmium::Way&) {
|
|
||||||
++ways;
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation(osmium::Relation&) {
|
|
||||||
++relations;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
if (argc != 2) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string input_filename = argv[1];
|
|
||||||
|
|
||||||
osmium::io::Reader reader(input_filename);
|
|
||||||
|
|
||||||
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";
|
|
||||||
}
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
The code in this file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
#include <osmium/handler.hpp>
|
|
||||||
#include <osmium/visitor.hpp>
|
|
||||||
|
|
||||||
struct CountHandler : public osmium::handler::Handler {
|
|
||||||
|
|
||||||
uint64_t counter = 0;
|
|
||||||
uint64_t all = 0;
|
|
||||||
|
|
||||||
void node(osmium::Node& node) {
|
|
||||||
++all;
|
|
||||||
const char* amenity = node.tags().get_value_by_key("amenity");
|
|
||||||
if (amenity && !strcmp(amenity, "post_box")) {
|
|
||||||
++counter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void way(osmium::Way&) {
|
|
||||||
++all;
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation(osmium::Relation&) {
|
|
||||||
++all;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
if (argc != 2) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string input_filename = argv[1];
|
|
||||||
|
|
||||||
osmium::io::Reader reader(input_filename);
|
|
||||||
|
|
||||||
CountHandler handler;
|
|
||||||
osmium::apply(reader, handler);
|
|
||||||
reader.close();
|
|
||||||
|
|
||||||
std::cout << "r_all=" << handler.all << " r_counter=" << handler.counter << "\n";
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
The code in this file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <osmium/index/map/all.hpp>
|
|
||||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
|
||||||
#include <osmium/visitor.hpp>
|
|
||||||
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
#include <osmium/handler.hpp>
|
|
||||||
|
|
||||||
typedef osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location> index_type;
|
|
||||||
|
|
||||||
typedef osmium::handler::NodeLocationsForWays<index_type> location_handler_type;
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
if (argc != 3) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " OSMFILE FORMAT\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string input_filename = argv[1];
|
|
||||||
std::string location_store = argv[2];
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
osmium::apply(reader, location_handler);
|
|
||||||
reader.close();
|
|
||||||
}
|
|
||||||
|
|
@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
This benchmarks compares the run time for statically vs. dynamically
|
|
||||||
configured index maps. You can configure index maps at compile-time using
|
|
||||||
typedefs or at run-time using polymorphism.
|
|
||||||
|
|
||||||
This will read the input file into a buffer and then run the
|
|
||||||
NodeLocationForWays handler multiple times over the complete data. The
|
|
||||||
number of runs depends on the size of the input, but is never smaller
|
|
||||||
than 10.
|
|
||||||
|
|
||||||
Do not run this with very large input files! It will need about 10 times
|
|
||||||
as much RAM as the file size of the input file.
|
|
||||||
|
|
||||||
The code in this file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <chrono>
|
|
||||||
#include <cmath>
|
|
||||||
#include <iostream>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
#include <osmium/index/map/all.hpp>
|
|
||||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
|
||||||
#include <osmium/visitor.hpp>
|
|
||||||
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
#include <osmium/handler.hpp>
|
|
||||||
|
|
||||||
typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> static_index_type;
|
|
||||||
const std::string location_store="sparse_mem_array";
|
|
||||||
|
|
||||||
typedef osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location> dynamic_index_type;
|
|
||||||
|
|
||||||
typedef osmium::handler::NodeLocationsForWays<static_index_type> static_location_handler_type;
|
|
||||||
typedef osmium::handler::NodeLocationsForWays<dynamic_index_type> dynamic_location_handler_type;
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
if (argc != 2) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string input_filename = argv[1];
|
|
||||||
|
|
||||||
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 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";
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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_type static_index;
|
|
||||||
static_location_handler_type static_location_handler(static_index);
|
|
||||||
|
|
||||||
auto start = std::chrono::steady_clock::now();
|
|
||||||
osmium::apply(tmp_buffer, static_location_handler);
|
|
||||||
auto end = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// dynamic index
|
|
||||||
osmium::memory::Buffer tmp_buffer(buffer.committed());
|
|
||||||
for (const auto& item : buffer) {
|
|
||||||
tmp_buffer.add_item(item);
|
|
||||||
tmp_buffer.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
auto start = std::chrono::steady_clock::now();
|
|
||||||
osmium::apply(tmp_buffer, dynamic_location_handler);
|
|
||||||
auto end = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double static_avg = static_sum/runs;
|
|
||||||
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";
|
|
||||||
|
|
||||||
double rfactor = 100.0;
|
|
||||||
double diff_min = std::round((dynamic_min - static_min) * rfactor) / rfactor;
|
|
||||||
double diff_avg = std::round((dynamic_avg - static_avg) * rfactor) / rfactor;
|
|
||||||
double diff_max = std::round((dynamic_max - static_max) * rfactor) / rfactor;
|
|
||||||
|
|
||||||
double prfactor = 10.0;
|
|
||||||
double percent_min = std::round((100.0 * diff_min / static_min) * prfactor) / prfactor;
|
|
||||||
double percent_avg = std::round((100.0 * diff_avg / static_avg) * prfactor) / prfactor;
|
|
||||||
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";
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
The code in this file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
#include <osmium/io/any_output.hpp>
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
if (argc != 3) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " INPUT-FILE OUTPUT-FILE\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
while (osmium::memory::Buffer buffer = reader.read()) {
|
|
||||||
writer(std::move(buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.close();
|
|
||||||
reader.close();
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# run_benchmark_count.sh
|
|
||||||
#
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
BENCHMARK_NAME=count
|
|
||||||
|
|
||||||
. @CMAKE_BINARY_DIR@/benchmarks/setup.sh
|
|
||||||
|
|
||||||
CMD=$OB_DIR/osmium_benchmark_$BENCHMARK_NAME
|
|
||||||
|
|
||||||
echo "# file size num mem time cpu_kernel cpu_user cpu_percent cmd options"
|
|
||||||
for data in $OB_DATA_FILES; do
|
|
||||||
filename=`basename $data`
|
|
||||||
filesize=`stat --format="%s" --dereference $data`
|
|
||||||
for n in $OB_SEQ; do
|
|
||||||
$OB_TIME_CMD -f "$filename $filesize $n $OB_TIME_FORMAT" $CMD $data 2>&1 >/dev/null | sed -e "s%$DATA_DIR/%%" | sed -e "s%$OB_DIR/%%"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# run_benchmark_count_tag.sh
|
|
||||||
#
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
BENCHMARK_NAME=count_tag
|
|
||||||
|
|
||||||
. @CMAKE_BINARY_DIR@/benchmarks/setup.sh
|
|
||||||
|
|
||||||
CMD=$OB_DIR/osmium_benchmark_$BENCHMARK_NAME
|
|
||||||
|
|
||||||
echo "# file size num mem time cpu_kernel cpu_user cpu_percent cmd options"
|
|
||||||
for data in $OB_DATA_FILES; do
|
|
||||||
filename=`basename $data`
|
|
||||||
filesize=`stat --format="%s" --dereference $data`
|
|
||||||
for n in $OB_SEQ; do
|
|
||||||
$OB_TIME_CMD -f "$filename $filesize $n $OB_TIME_FORMAT" $CMD $data 2>&1 >/dev/null | sed -e "s%$DATA_DIR/%%" | sed -e "s%$OB_DIR/%%"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# run_benchmark_index_map.sh
|
|
||||||
#
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
BENCHMARK_NAME=index_map
|
|
||||||
|
|
||||||
. @CMAKE_BINARY_DIR@/benchmarks/setup.sh
|
|
||||||
|
|
||||||
CMD=$OB_DIR/osmium_benchmark_$BENCHMARK_NAME
|
|
||||||
|
|
||||||
#MAPS="sparse_mem_map sparse_mem_table sparse_mem_array sparse_mmap_array sparse_file_array dense_mem_array dense_mmap_array dense_file_array"
|
|
||||||
MAPS="sparse_mem_map sparse_mem_table sparse_mem_array sparse_mmap_array sparse_file_array"
|
|
||||||
|
|
||||||
echo "# file size num mem time cpu_kernel cpu_user cpu_percent cmd options"
|
|
||||||
for data in $OB_DATA_FILES; do
|
|
||||||
filename=`basename $data`
|
|
||||||
filesize=`stat --format="%s" --dereference $data`
|
|
||||||
for map in $MAPS; do
|
|
||||||
for n in $OB_SEQ; do
|
|
||||||
$OB_TIME_CMD -f "$filename $filesize $n $OB_TIME_FORMAT" $CMD $data $map 2>&1 >/dev/null | sed -e "s%$DATA_DIR/%%" | sed -e "s%$OB_DIR/%%"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# run_benchmark_static_vs_dynamic_index.sh
|
|
||||||
#
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
BENCHMARK_NAME=static_vs_dynamic_index
|
|
||||||
|
|
||||||
. @CMAKE_BINARY_DIR@/benchmarks/setup.sh
|
|
||||||
|
|
||||||
CMD=$OB_DIR/osmium_benchmark_$BENCHMARK_NAME
|
|
||||||
|
|
||||||
for data in $OB_DATA_FILES; do
|
|
||||||
filesize=`stat --format="%s" --dereference $data`
|
|
||||||
if [ $filesize -lt 500000000 ]; then
|
|
||||||
echo "========================"
|
|
||||||
$CMD $data
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# run_benchmark_write_pbf.sh
|
|
||||||
#
|
|
||||||
# Will read the input file and after reading it into memory completely,
|
|
||||||
# write it to /dev/null. Because this will need the time to read *and* write
|
|
||||||
# the file, it will report the times for reading and writing. You can
|
|
||||||
# subtract the times needed for the "count" benchmark to (roughly) get the
|
|
||||||
# write times.
|
|
||||||
#
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
BENCHMARK_NAME=write_pbf
|
|
||||||
|
|
||||||
. @CMAKE_BINARY_DIR@/benchmarks/setup.sh
|
|
||||||
|
|
||||||
CMD=$OB_DIR/osmium_benchmark_$BENCHMARK_NAME
|
|
||||||
|
|
||||||
echo "# file size num mem time cpu_kernel cpu_user cpu_percent cmd options"
|
|
||||||
for data in $OB_DATA_FILES; do
|
|
||||||
filename=`basename $data`
|
|
||||||
filesize=`stat --format="%s" --dereference $data`
|
|
||||||
for n in $OB_SEQ; do
|
|
||||||
$OB_TIME_CMD -f "$filename $filesize $n $OB_TIME_FORMAT" $CMD $data /dev/null 2>&1 >/dev/null | sed -e "s%$DATA_DIR/%%" | sed -e "s%$OB_DIR/%%"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# run_benchmarks.sh
|
|
||||||
#
|
|
||||||
# Run all benchmarks.
|
|
||||||
#
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
for benchmark in @CMAKE_BINARY_DIR@/benchmarks/run_benchmark_*.sh; do
|
|
||||||
name=`basename $benchmark`
|
|
||||||
echo "Running $name..."
|
|
||||||
$benchmark
|
|
||||||
done
|
|
||||||
|
|
34
third_party/libosmium/benchmarks/setup.sh
vendored
34
third_party/libosmium/benchmarks/setup.sh
vendored
@ -1,34 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# setup.sh
|
|
||||||
#
|
|
||||||
|
|
||||||
if [ -z $DATA_DIR ]; then
|
|
||||||
echo "Please set DATA_DIR environment variable before running benchmark"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
OB_DIR=@CMAKE_BINARY_DIR@/benchmarks
|
|
||||||
|
|
||||||
OB_RUNS=3
|
|
||||||
OB_SEQ=`seq -s' ' 1 $OB_RUNS`
|
|
||||||
|
|
||||||
OB_TIME_CMD=/usr/bin/time
|
|
||||||
OB_TIME_FORMAT="%M %e %S %U %P %C"
|
|
||||||
|
|
||||||
OB_DATA_FILES=`find -L $DATA_DIR -mindepth 1 -maxdepth 1 -type f | sort`
|
|
||||||
|
|
||||||
echo "BENCHMARK: $BENCHMARK_NAME"
|
|
||||||
echo "---------------------"
|
|
||||||
echo "CPU:"
|
|
||||||
grep '^model name' /proc/cpuinfo | tail -1
|
|
||||||
grep '^cpu MHz' /proc/cpuinfo | tail -1
|
|
||||||
grep '^cpu cores' /proc/cpuinfo | tail -1
|
|
||||||
grep '^siblings' /proc/cpuinfo | tail -1
|
|
||||||
|
|
||||||
echo "---------------------"
|
|
||||||
echo "MEMORY:"
|
|
||||||
free
|
|
||||||
echo "---------------------"
|
|
||||||
echo "RESULTS:"
|
|
||||||
|
|
153
third_party/libosmium/cmake/FindGem.cmake
vendored
153
third_party/libosmium/cmake/FindGem.cmake
vendored
@ -1,153 +0,0 @@
|
|||||||
# Author thomas.roehr@dfki.de
|
|
||||||
#
|
|
||||||
# Version 0.3 2013-07-02
|
|
||||||
# - rely on `gem content` to find library and header
|
|
||||||
# - introduce GEM_OS_PKG to allow search via pkgconfig
|
|
||||||
# Version 0.2 2010-01-14
|
|
||||||
# - add support for searching for multiple gems
|
|
||||||
# Version 0.1 2010-12-15
|
|
||||||
# - support basic search functionality
|
|
||||||
# - tested to find rice
|
|
||||||
#
|
|
||||||
# OUTPUT:
|
|
||||||
#
|
|
||||||
# GEM_INCLUDE_DIRS After successful search contains the include directores
|
|
||||||
#
|
|
||||||
# GEM_LIBRARIES After successful search contains the full path of each found library
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# set(GEM_DEBUG TRUE)
|
|
||||||
# find_package(Gem COMPONENTS rice hoe)
|
|
||||||
# include_directories(${GEM_INCLUDE_DIRS})
|
|
||||||
# target_link_libraries(${GEM_LIBRARIES}
|
|
||||||
#
|
|
||||||
# in case pkg-config should be used to search for the os pkg, set GEM_OS_PKG, i.e.
|
|
||||||
# set(GEM_OS_PKG TRUE)
|
|
||||||
#
|
|
||||||
# Check for how 'gem' should be called
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_program(GEM_EXECUTABLE
|
|
||||||
NAMES "gem${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}"
|
|
||||||
"gem${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}"
|
|
||||||
"gem-${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}"
|
|
||||||
"gem-${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}"
|
|
||||||
"gem${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}${RUBY_VERSION_PATCH}"
|
|
||||||
"gem${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}.${RUBY_VERSION_PATCH}"
|
|
||||||
"gem-${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}${RUBY_VERSION_PATCH}"
|
|
||||||
"gem-${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}.${RUBY_VERSION_PATCH}"
|
|
||||||
"gem")
|
|
||||||
|
|
||||||
# Making backward compatible
|
|
||||||
if(Gem_DEBUG)
|
|
||||||
set(GEM_DEBUG TRUE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT GEM_EXECUTABLE)
|
|
||||||
MESSAGE(FATAL_ERROR "Could not find the gem executable - install 'gem' first")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT Gem_FIND_COMPONENTS)
|
|
||||||
MESSAGE(FATAL_ERROR "If searching for a Gem you have to provide COMPONENTS with the name of the gem")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
foreach(Gem_NAME ${Gem_FIND_COMPONENTS})
|
|
||||||
set(GEM_${Gem_NAME}_FOUND TRUE)
|
|
||||||
list(APPEND components_found_vars GEM_${Gem_NAME}_FOUND)
|
|
||||||
# If the gem is installed as a gem
|
|
||||||
if(NOT GEM_OS_PKG)
|
|
||||||
set(GEM_HOME ENV{GEM_HOME})
|
|
||||||
|
|
||||||
# Use `gem content <gem-name>` to extract current information about installed gems
|
|
||||||
# Store the information into ${GEM_LOCAL_INFO}
|
|
||||||
EXECUTE_PROCESS(COMMAND ${GEM_EXECUTABLE} content ${Gem_NAME}
|
|
||||||
RESULT_VARIABLE GEM_RUN_RESULT
|
|
||||||
OUTPUT_VARIABLE GEM_LOCAL_INFO)
|
|
||||||
|
|
||||||
if(GEM_RUN_RESULT STREQUAL "0")
|
|
||||||
list(APPEND FOUND_GEMS ${Gem_NAME})
|
|
||||||
set(_library_NAME_PATTERN lib${Gem_NAME}.a
|
|
||||||
lib${Gem_NAME}.so
|
|
||||||
lib${Gem_NAME}.dylib
|
|
||||||
${Gem_NAME}.a
|
|
||||||
${Gem_NAME}.so
|
|
||||||
${Gem_NAME}.dylib
|
|
||||||
.*.a
|
|
||||||
.*.so
|
|
||||||
.*.dylib
|
|
||||||
)
|
|
||||||
|
|
||||||
set(_header_SUFFIX_PATTERN
|
|
||||||
.h
|
|
||||||
.hh
|
|
||||||
.hpp
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create a list from the output results of the gem command
|
|
||||||
string(REPLACE "\n" ";" GEM_CONTENT_LIST "${GEM_LOCAL_INFO}")
|
|
||||||
foreach(_gem_CONTENT_PATH ${GEM_CONTENT_LIST})
|
|
||||||
|
|
||||||
# Convert so that only '/' Unix path separator are being using
|
|
||||||
# needed to do proper regex matching
|
|
||||||
FILE(TO_CMAKE_PATH ${_gem_CONTENT_PATH} gem_CONTENT_PATH)
|
|
||||||
|
|
||||||
# Identify library -- checking for a library in the gems 'lib' (sub)directory
|
|
||||||
# Search for an existing library, but only within the gems folder
|
|
||||||
foreach(_library_NAME ${_library_NAME_PATTERN})
|
|
||||||
STRING(REGEX MATCH ".*${Gem_NAME}.*/lib/.*${_library_NAME}$" GEM_PATH_INFO "${gem_CONTENT_PATH}")
|
|
||||||
if(NOT "${GEM_PATH_INFO}" STREQUAL "")
|
|
||||||
list(APPEND GEM_LIBRARIES ${GEM_PATH_INFO})
|
|
||||||
break()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# Identify headers
|
|
||||||
# Checking for available headers in an include directory
|
|
||||||
foreach(_header_PATTERN ${_header_SUFFIX_PATTERN})
|
|
||||||
STRING(REGEX MATCH ".*${Gem_NAME}.*/include/.*${_header_PATTERN}$" GEM_PATH_INFO "${gem_CONTENT_PATH}")
|
|
||||||
if(NOT "${GEM_PATH_INFO}" STREQUAL "")
|
|
||||||
STRING(REGEX REPLACE "(.*${Gem_NAME}.*/include/).*${_header_PATTERN}$" "\\1" GEM_PATH_INFO "${gem_CONTENT_PATH}")
|
|
||||||
list(APPEND GEM_INCLUDE_DIRS ${GEM_PATH_INFO})
|
|
||||||
break()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endforeach()
|
|
||||||
else()
|
|
||||||
set(GEM_${Gem_NAME}_FOUND FALSE)
|
|
||||||
endif()
|
|
||||||
else(NOT GEM_OS_PKG)
|
|
||||||
pkg_check_modules(GEM_PKG ${Gem_NAME})
|
|
||||||
set(GEM_${GEM_NAME}_FOUND GEM_PKG_FOUND)
|
|
||||||
set(GEM_INCLUDE_DIRS ${GEM_PKG_INCLUDE_DIRS})
|
|
||||||
set(GEM_LIBRARIES ${GEM_PKG_LIBRARIES} ${GEM_PKG_STATIC_LIBRARIES})
|
|
||||||
list(APPEND GEM_LIBRARIES ${GEM_PKG_LDFLAGS} ${GEM_PKG_STATIC_LDFLAGS})
|
|
||||||
list(APPEND GEM_LIBRARIES ${GEM_PKG_LDFLAGS_OTHER} ${GEM_PKG_STATIC_LDFLAGS_OTHER})
|
|
||||||
|
|
||||||
if(GEM_DEBUG)
|
|
||||||
message(STATUS "GEM_OS_PKG is defined")
|
|
||||||
message(STATUS "GEM_INCLUDE_DIRS ${GEM_INCLUDE_DIRS}")
|
|
||||||
message(STATUS "GEM_STATIC_LIBRARY_DIRS ${GEM_PKG_STATIC_LIBRARY_DIRS}")
|
|
||||||
message(STATUS "GEM_LIBRARY_DIRS ${GEM_PKG_STATIC_LIBRARY_DIRS}")
|
|
||||||
message(STATUS "GEM_STATIC_LIBRARIES ${GEM_PKG_STATIC_LIBRARIES}")
|
|
||||||
message(STATUS "GEM_LIBRARIES ${GEM_LIBRARIES}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(GEM_DEBUG)
|
|
||||||
message(STATUS "${Gem_NAME} library dir: ${GEM_LIBRARIES}")
|
|
||||||
message(STATUS "${Gem_NAME} include dir: ${GEM_INCLUDE_DIRS}")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# Compact the lists
|
|
||||||
if(DEFINED GEM_LIBRARIES)
|
|
||||||
LIST(REMOVE_DUPLICATES GEM_LIBRARIES)
|
|
||||||
endif()
|
|
||||||
if(DEFINED GEM_INCLUDE_DIRS)
|
|
||||||
LIST(REMOVE_DUPLICATES GEM_INCLUDE_DIRS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_package_handle_standard_args(GEM
|
|
||||||
REQUIRED_VARS ${components_found_vars}
|
|
||||||
FAIL_MESSAGE "Could not find all required gems")
|
|
||||||
|
|
318
third_party/libosmium/cmake/FindOsmium.cmake
vendored
318
third_party/libosmium/cmake/FindOsmium.cmake
vendored
@ -1,318 +0,0 @@
|
|||||||
#----------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# FindOsmium.cmake
|
|
||||||
#
|
|
||||||
# Find the Libosmium headers and, optionally, several components needed for
|
|
||||||
# different Libosmium functions.
|
|
||||||
#
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
#
|
|
||||||
# Copy this file somewhere into your project directory, where cmake can
|
|
||||||
# find it. Usually this will be a directory called "cmake" which you can
|
|
||||||
# add to the CMake module search path with the following line in your
|
|
||||||
# CMakeLists.txt:
|
|
||||||
#
|
|
||||||
# list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
|
||||||
#
|
|
||||||
# Then add the following in your CMakeLists.txt:
|
|
||||||
#
|
|
||||||
# find_package(Osmium REQUIRED COMPONENTS <XXX>)
|
|
||||||
# include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
|
|
||||||
#
|
|
||||||
# For the <XXX> substitute a space separated list of one or more of the
|
|
||||||
# following components:
|
|
||||||
#
|
|
||||||
# pbf - include libraries needed for PBF input and output
|
|
||||||
# xml - include libraries needed for XML input and output
|
|
||||||
# io - include libraries needed for any type of input/output
|
|
||||||
# geos - include if you want to use any of the GEOS functions
|
|
||||||
# gdal - include if you want to use any of the OGR functions
|
|
||||||
# proj - include if you want to use any of the Proj.4 functions
|
|
||||||
# sparsehash - include if you use the sparsehash index
|
|
||||||
#
|
|
||||||
# You can check for success with something like this:
|
|
||||||
#
|
|
||||||
# if(NOT OSMIUM_FOUND)
|
|
||||||
# message(WARNING "Libosmium not found!\n")
|
|
||||||
# endif()
|
|
||||||
#
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Variables:
|
|
||||||
#
|
|
||||||
# OSMIUM_FOUND - True if Osmium found.
|
|
||||||
# OSMIUM_INCLUDE_DIRS - Where to find include files.
|
|
||||||
# OSMIUM_XML_LIBRARIES - Libraries needed for XML I/O.
|
|
||||||
# OSMIUM_PBF_LIBRARIES - Libraries needed for PBF I/O.
|
|
||||||
# OSMIUM_IO_LIBRARIES - Libraries needed for XML or PBF I/O.
|
|
||||||
# OSMIUM_LIBRARIES - All libraries Osmium uses somewhere.
|
|
||||||
#
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Look for the header file.
|
|
||||||
find_path(OSMIUM_INCLUDE_DIR osmium/osm.hpp
|
|
||||||
PATH_SUFFIXES include
|
|
||||||
PATHS
|
|
||||||
../libosmium
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/opt/local # DarwinPorts
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
set(OSMIUM_INCLUDE_DIRS "${OSMIUM_INCLUDE_DIR}")
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Check for optional components
|
|
||||||
#
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
if(Osmium_FIND_COMPONENTS)
|
|
||||||
foreach(_component ${Osmium_FIND_COMPONENTS})
|
|
||||||
string(TOUPPER ${_component} _component_uppercase)
|
|
||||||
set(Osmium_USE_${_component_uppercase} TRUE)
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
# Component 'io' is an alias for 'pbf' and 'xml'
|
|
||||||
if(Osmium_USE_IO)
|
|
||||||
set(Osmium_USE_PBF TRUE)
|
|
||||||
set(Osmium_USE_XML TRUE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
# Component 'ogr' is an alias for 'gdal'
|
|
||||||
if(Osmium_USE_OGR)
|
|
||||||
set(Osmium_USE_GDAL TRUE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
# Component 'pbf'
|
|
||||||
if(Osmium_USE_PBF)
|
|
||||||
find_package(ZLIB)
|
|
||||||
find_package(Threads)
|
|
||||||
|
|
||||||
list(APPEND OSMIUM_EXTRA_FIND_VARS ZLIB_FOUND Threads_FOUND)
|
|
||||||
if(ZLIB_FOUND AND Threads_FOUND)
|
|
||||||
list(APPEND OSMIUM_PBF_LIBRARIES
|
|
||||||
${ZLIB_LIBRARIES}
|
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
|
||||||
)
|
|
||||||
if(WIN32)
|
|
||||||
list(APPEND OSMIUM_PBF_LIBRARIES ws2_32)
|
|
||||||
endif()
|
|
||||||
list(APPEND OSMIUM_INCLUDE_DIRS
|
|
||||||
${ZLIB_INCLUDE_DIR}
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
message(WARNING "Osmium: Can not find some libraries for PBF input/output, please install them or configure the paths.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
# Component 'xml'
|
|
||||||
if(Osmium_USE_XML)
|
|
||||||
find_package(EXPAT)
|
|
||||||
find_package(BZip2)
|
|
||||||
find_package(ZLIB)
|
|
||||||
find_package(Threads)
|
|
||||||
|
|
||||||
list(APPEND OSMIUM_EXTRA_FIND_VARS EXPAT_FOUND BZIP2_FOUND ZLIB_FOUND Threads_FOUND)
|
|
||||||
if(EXPAT_FOUND AND BZIP2_FOUND AND ZLIB_FOUND AND Threads_FOUND)
|
|
||||||
list(APPEND OSMIUM_XML_LIBRARIES
|
|
||||||
${EXPAT_LIBRARIES}
|
|
||||||
${BZIP2_LIBRARIES}
|
|
||||||
${ZLIB_LIBRARIES}
|
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
|
||||||
)
|
|
||||||
list(APPEND OSMIUM_INCLUDE_DIRS
|
|
||||||
${EXPAT_INCLUDE_DIR}
|
|
||||||
${BZIP2_INCLUDE_DIR}
|
|
||||||
${ZLIB_INCLUDE_DIR}
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
message(WARNING "Osmium: Can not find some libraries for XML input/output, please install them or configure the paths.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
list(APPEND OSMIUM_IO_LIBRARIES
|
|
||||||
${OSMIUM_PBF_LIBRARIES}
|
|
||||||
${OSMIUM_XML_LIBRARIES}
|
|
||||||
)
|
|
||||||
|
|
||||||
list(APPEND OSMIUM_LIBRARIES
|
|
||||||
${OSMIUM_IO_LIBRARIES}
|
|
||||||
)
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
# Component 'geos'
|
|
||||||
if(Osmium_USE_GEOS)
|
|
||||||
find_path(GEOS_INCLUDE_DIR geos/geom.h)
|
|
||||||
find_library(GEOS_LIBRARY NAMES geos)
|
|
||||||
|
|
||||||
list(APPEND OSMIUM_EXTRA_FIND_VARS GEOS_INCLUDE_DIR GEOS_LIBRARY)
|
|
||||||
if(GEOS_INCLUDE_DIR AND GEOS_LIBRARY)
|
|
||||||
SET(GEOS_FOUND 1)
|
|
||||||
list(APPEND OSMIUM_LIBRARIES ${GEOS_LIBRARY})
|
|
||||||
list(APPEND OSMIUM_INCLUDE_DIRS ${GEOS_INCLUDE_DIR})
|
|
||||||
else()
|
|
||||||
message(WARNING "Osmium: GEOS library is required but not found, please install it or configure the paths.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
# Component 'gdal' (alias 'ogr')
|
|
||||||
if(Osmium_USE_GDAL)
|
|
||||||
find_package(GDAL)
|
|
||||||
|
|
||||||
list(APPEND OSMIUM_EXTRA_FIND_VARS GDAL_FOUND)
|
|
||||||
if(GDAL_FOUND)
|
|
||||||
list(APPEND OSMIUM_LIBRARIES ${GDAL_LIBRARIES})
|
|
||||||
list(APPEND OSMIUM_INCLUDE_DIRS ${GDAL_INCLUDE_DIRS})
|
|
||||||
else()
|
|
||||||
message(WARNING "Osmium: GDAL library is required but not found, please install it or configure the paths.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
# Component 'proj'
|
|
||||||
if(Osmium_USE_PROJ)
|
|
||||||
find_path(PROJ_INCLUDE_DIR proj_api.h)
|
|
||||||
find_library(PROJ_LIBRARY NAMES proj)
|
|
||||||
|
|
||||||
list(APPEND OSMIUM_EXTRA_FIND_VARS PROJ_INCLUDE_DIR PROJ_LIBRARY)
|
|
||||||
if(PROJ_INCLUDE_DIR AND PROJ_LIBRARY)
|
|
||||||
set(PROJ_FOUND 1)
|
|
||||||
list(APPEND OSMIUM_LIBRARIES ${PROJ_LIBRARY})
|
|
||||||
list(APPEND OSMIUM_INCLUDE_DIRS ${PROJ_INCLUDE_DIR})
|
|
||||||
else()
|
|
||||||
message(WARNING "Osmium: PROJ.4 library is required but not found, please install it or configure the paths.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
# Component 'sparsehash'
|
|
||||||
if(Osmium_USE_SPARSEHASH)
|
|
||||||
find_path(SPARSEHASH_INCLUDE_DIR google/sparsetable)
|
|
||||||
|
|
||||||
list(APPEND OSMIUM_EXTRA_FIND_VARS SPARSEHASH_INCLUDE_DIR)
|
|
||||||
if(SPARSEHASH_INCLUDE_DIR)
|
|
||||||
# Find size of sparsetable::size_type. This does not work on older
|
|
||||||
# CMake versions because they can do this check only in C, not in C++.
|
|
||||||
if (NOT CMAKE_VERSION VERSION_LESS 3.0)
|
|
||||||
include(CheckTypeSize)
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${SPARSEHASH_INCLUDE_DIR})
|
|
||||||
set(CMAKE_EXTRA_INCLUDE_FILES "google/sparsetable")
|
|
||||||
check_type_size("google::sparsetable<int>::size_type" SPARSETABLE_SIZE_TYPE LANGUAGE CXX)
|
|
||||||
set(CMAKE_EXTRA_INCLUDE_FILES)
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES)
|
|
||||||
else()
|
|
||||||
set(SPARSETABLE_SIZE_TYPE ${CMAKE_SIZEOF_VOID_P})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Sparsetable::size_type must be at least 8 bytes (64bit), otherwise
|
|
||||||
# OSM object IDs will not fit.
|
|
||||||
if(SPARSETABLE_SIZE_TYPE GREATER 7)
|
|
||||||
set(SPARSEHASH_FOUND 1)
|
|
||||||
add_definitions(-DOSMIUM_WITH_SPARSEHASH=${SPARSEHASH_FOUND})
|
|
||||||
list(APPEND OSMIUM_INCLUDE_DIRS ${SPARSEHASH_INCLUDE_DIR})
|
|
||||||
else()
|
|
||||||
message(WARNING "Osmium: Disabled Google SparseHash library on 32bit system (size_type=${SPARSETABLE_SIZE_TYPE}).")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
message(WARNING "Osmium: Google SparseHash library is required but not found, please install it or configure the paths.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
|
|
||||||
list(REMOVE_DUPLICATES OSMIUM_INCLUDE_DIRS)
|
|
||||||
|
|
||||||
if(OSMIUM_XML_LIBRARIES)
|
|
||||||
list(REMOVE_DUPLICATES OSMIUM_XML_LIBRARIES)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(OSMIUM_PBF_LIBRARIES)
|
|
||||||
list(REMOVE_DUPLICATES OSMIUM_PBF_LIBRARIES)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(OSMIUM_IO_LIBRARIES)
|
|
||||||
list(REMOVE_DUPLICATES OSMIUM_IO_LIBRARIES)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(OSMIUM_LIBRARIES)
|
|
||||||
list(REMOVE_DUPLICATES OSMIUM_LIBRARIES)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Check that all required libraries are available
|
|
||||||
#
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
if (OSMIUM_EXTRA_FIND_VARS)
|
|
||||||
list(REMOVE_DUPLICATES OSMIUM_EXTRA_FIND_VARS)
|
|
||||||
endif()
|
|
||||||
# Handle the QUIETLY and REQUIRED arguments and set OSMIUM_FOUND to TRUE if
|
|
||||||
# all listed variables are TRUE.
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(Osmium REQUIRED_VARS OSMIUM_INCLUDE_DIR ${OSMIUM_EXTRA_FIND_VARS})
|
|
||||||
unset(OSMIUM_EXTRA_FIND_VARS)
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Add compiler flags
|
|
||||||
#
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64)
|
|
||||||
|
|
||||||
if(MSVC)
|
|
||||||
add_definitions(-wd4996)
|
|
||||||
|
|
||||||
# Disable warning C4068: "unknown pragma" because we want it to ignore
|
|
||||||
# pragmas for other compilers.
|
|
||||||
add_definitions(-wd4068)
|
|
||||||
|
|
||||||
# Disable warning C4715: "not all control paths return a value" because
|
|
||||||
# it generates too many false positives.
|
|
||||||
add_definitions(-wd4715)
|
|
||||||
|
|
||||||
# Disable warning C4351: new behavior: elements of array '...' will be
|
|
||||||
# default initialized. The new behaviour is correct and we don't support
|
|
||||||
# old compilers anyway.
|
|
||||||
add_definitions(-wd4351)
|
|
||||||
|
|
||||||
add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_WARNINGS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(APPLE)
|
|
||||||
# following only available from cmake 2.8.12:
|
|
||||||
# add_compile_options(-stdlib=libc++)
|
|
||||||
# so using this instead:
|
|
||||||
add_definitions(-stdlib=libc++)
|
|
||||||
set(LDFLAGS ${LDFLAGS} -stdlib=libc++)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
|
|
||||||
# This is a set of recommended warning options that can be added when compiling
|
|
||||||
# libosmium code.
|
|
||||||
if(MSVC)
|
|
||||||
set(OSMIUM_WARNING_OPTIONS "/W3 /wd4514" CACHE STRING "Recommended warning options for libosmium")
|
|
||||||
else()
|
|
||||||
set(OSMIUM_WARNING_OPTIONS "-Wall -Wextra -pedantic -Wredundant-decls -Wdisabled-optimization -Wctor-dtor-privacy -Wnon-virtual-dtor -Woverloaded-virtual -Wsign-promo -Wold-style-cast" CACHE STRING "Recommended warning options for libosmium")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(OSMIUM_DRACONIC_CLANG_OPTIONS "-Wdocumentation -Wunused-exception-parameter -Wmissing-declarations -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-unused-macros -Wno-exit-time-destructors -Wno-global-constructors -Wno-padded -Wno-switch-enum -Wno-missing-prototypes -Wno-weak-vtables -Wno-cast-align -Wno-float-equal")
|
|
||||||
|
|
||||||
if(Osmium_DEBUG)
|
|
||||||
message(STATUS "OSMIUM_XML_LIBRARIES=" ${OSMIUM_XML_LIBRARIES})
|
|
||||||
message(STATUS "OSMIUM_PBF_LIBRARIES=" ${OSMIUM_PBF_LIBRARIES})
|
|
||||||
message(STATUS "OSMIUM_IO_LIBRARIES=" ${OSMIUM_IO_LIBRARIES})
|
|
||||||
message(STATUS "OSMIUM_LIBRARIES=" ${OSMIUM_LIBRARIES})
|
|
||||||
message(STATUS "OSMIUM_INCLUDE_DIRS=" ${OSMIUM_INCLUDE_DIRS})
|
|
||||||
endif()
|
|
||||||
|
|
3
third_party/libosmium/cmake/README
vendored
3
third_party/libosmium/cmake/README
vendored
@ -1,3 +0,0 @@
|
|||||||
|
|
||||||
FindGem.cmake from https://github.com/rock-core/base-cmake
|
|
||||||
|
|
15
third_party/libosmium/cmake/build.bat
vendored
15
third_party/libosmium/cmake/build.bat
vendored
@ -1,15 +0,0 @@
|
|||||||
call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
|
|
||||||
set CMAKE_PREFIX_PATH=C:\PROJ
|
|
||||||
set VERSION=Debug
|
|
||||||
set TESTS=ON
|
|
||||||
set ALLHPPS=ON
|
|
||||||
set PREFIX=d:\libs18d
|
|
||||||
set BOOST_ROOT=d:\boost
|
|
||||||
|
|
||||||
cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%PREFIX% -DBOOST_ROOT=%BOOST_ROOT% -DBoost_USE_STATIC_LIBS=ON -DBUILD_TESTING=%TESTS% -DBUILD_TRY_HPPS=%ALLHPPS$ -T CTP_Nov2013
|
|
||||||
msbuild /clp:Verbosity=minimal /nologo libosmium.sln /flp1:logfile=build_errors.txt;errorsonly /flp2:logfile=build_warnings.txt;warningsonly
|
|
||||||
set PATH=%PATH%;%PREFIX%/bin
|
|
||||||
|
|
||||||
del test\osm-testdata\*.db
|
|
||||||
del test\osm-testdata\*.json
|
|
||||||
if "%TESTS%"=="ON" ctest -VV >build_tests.log
|
|
43
third_party/libosmium/cmake/iwyu.sh
vendored
43
third_party/libosmium/cmake/iwyu.sh
vendored
@ -1,43 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# This will run IWYU (Include What You Use) on includes files. The iwyu
|
|
||||||
# program isn't very reliable and crashes often, but is still useful.
|
|
||||||
#
|
|
||||||
# TODO: This script should be integrated with cmake in some way...
|
|
||||||
#
|
|
||||||
|
|
||||||
cmdline="iwyu -Xiwyu --mapping_file=osmium.imp -std=c++11 -I include"
|
|
||||||
|
|
||||||
log=build/iwyu.log
|
|
||||||
|
|
||||||
mkdir -p build/check_reports
|
|
||||||
|
|
||||||
echo "INCLUDE WHAT YOU USE REPORT:" >$log
|
|
||||||
|
|
||||||
allok=yes
|
|
||||||
|
|
||||||
for file in `find include/osmium -name \*.hpp | sort`; do
|
|
||||||
mkdir -p `dirname build/check_reports/$file`
|
|
||||||
ifile="build/check_reports/${file%.hpp}.iwyu"
|
|
||||||
$cmdline $file >$ifile 2>&1
|
|
||||||
if grep -q 'has correct #includes/fwd-decls' ${ifile}; then
|
|
||||||
echo "\n\033[1m\033[32m========\033[0m \033[1m${file}\033[0m" >>$log
|
|
||||||
echo "[OK] ${file}"
|
|
||||||
elif grep -q 'Assertion failed' ${ifile}; then
|
|
||||||
echo "\n\033[1m======== ${file}\033[0m" >>$log
|
|
||||||
echo "[--] ${file}"
|
|
||||||
allok=no
|
|
||||||
else
|
|
||||||
echo "\n\033[1m\033[31m========\033[0m \033[1m${file}\033[0m" >>$log
|
|
||||||
echo "[ ] ${file}"
|
|
||||||
allok=no
|
|
||||||
fi
|
|
||||||
cat $ifile >>$log
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "$allok" = "yes" ]; then
|
|
||||||
echo "All files OK"
|
|
||||||
else
|
|
||||||
echo "There were errors"
|
|
||||||
fi
|
|
||||||
|
|
33
third_party/libosmium/doc/CMakeLists.txt
vendored
33
third_party/libosmium/doc/CMakeLists.txt
vendored
@ -1,33 +0,0 @@
|
|||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# CMake Config
|
|
||||||
#
|
|
||||||
# Libosmium documentation
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
message(STATUS "Configuring documentation")
|
|
||||||
|
|
||||||
message(STATUS "Looking for doxygen")
|
|
||||||
find_package(Doxygen)
|
|
||||||
|
|
||||||
if(DOXYGEN_FOUND)
|
|
||||||
message(STATUS "Looking for doxygen - found")
|
|
||||||
configure_file(header.html ${CMAKE_CURRENT_BINARY_DIR}/header.html @ONLY)
|
|
||||||
configure_file(Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
|
|
||||||
add_custom_target(doc
|
|
||||||
${DOXYGEN_EXECUTABLE}
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
COMMENT "Generating API documentation with Doxygen" VERBATIM
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
message(STATUS "Looking for doxygen - not found")
|
|
||||||
message(STATUS " Disabled making of documentation.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
message(STATUS "Configuring documentation - done")
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
2313
third_party/libosmium/doc/Doxyfile.in
vendored
2313
third_party/libosmium/doc/Doxyfile.in
vendored
File diff suppressed because it is too large
Load Diff
8
third_party/libosmium/doc/README.md
vendored
8
third_party/libosmium/doc/README.md
vendored
@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
The `header.html` is created with:
|
|
||||||
|
|
||||||
`doxygen -w html header.html footer.html stylesheet.css`
|
|
||||||
|
|
||||||
This might have to be run again for newer Doxygen versions. After that add
|
|
||||||
changes back in.
|
|
||||||
|
|
26
third_party/libosmium/doc/doc.txt
vendored
26
third_party/libosmium/doc/doc.txt
vendored
@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
/**
|
|
||||||
* @mainpage
|
|
||||||
*
|
|
||||||
* Osmium is a fast and flexible C++ library for working with OpenStreetMap
|
|
||||||
* 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 .
|
|
||||||
*
|
|
||||||
* Osmium is free software and available under the Boost Software License.
|
|
||||||
* The source code is available at https://github.com/osmcode/libosmium .
|
|
||||||
*
|
|
||||||
* Osmium is a header-only library. You do not need to compile and link it,
|
|
||||||
* just include the headers you need.
|
|
||||||
*
|
|
||||||
* Everything in namespaces called "detail" is for internal Osmium use only,
|
|
||||||
* do not depend on it in your code. Do not include any include files in
|
|
||||||
* directories named "detail" directly. Include files in directories called
|
|
||||||
* "experimental" and everything in namespaces called "experimental" is
|
|
||||||
* unsupported and may change at any time regardless of the status of the rest
|
|
||||||
* of the library.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
56
third_party/libosmium/doc/header.html
vendored
56
third_party/libosmium/doc/header.html
vendored
@ -1,56 +0,0 @@
|
|||||||
<!-- HTML header for doxygen 1.8.8-->
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
||||||
<meta name="generator" content="Doxygen $doxygenversion"/>
|
|
||||||
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
|
|
||||||
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
|
|
||||||
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
|
|
||||||
<script type="text/javascript" src="$relpath^jquery.js"></script>
|
|
||||||
<script type="text/javascript" src="$relpath^dynsections.js"></script>
|
|
||||||
$treeview
|
|
||||||
$search
|
|
||||||
$mathjax
|
|
||||||
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
|
||||||
$extrastylesheet
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
|
||||||
|
|
||||||
<!--BEGIN TITLEAREA-->
|
|
||||||
<div id="titlearea">
|
|
||||||
<table cellspacing="0" cellpadding="0">
|
|
||||||
<tbody>
|
|
||||||
<tr style="height: 56px;">
|
|
||||||
<!--BEGIN PROJECT_LOGO-->
|
|
||||||
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
|
|
||||||
<!--END PROJECT_LOGO-->
|
|
||||||
<!--BEGIN PROJECT_NAME-->
|
|
||||||
<td style="padding-left: 0.5em;">
|
|
||||||
<div id="projectname">$projectname
|
|
||||||
<!--BEGIN PROJECT_NUMBER--> <span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
|
|
||||||
</div>
|
|
||||||
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
|
|
||||||
</td>
|
|
||||||
<!--END PROJECT_NAME-->
|
|
||||||
<!--BEGIN !PROJECT_NAME-->
|
|
||||||
<!--BEGIN PROJECT_BRIEF-->
|
|
||||||
<td style="padding-left: 0.5em;">
|
|
||||||
<div id="projectbrief">$projectbrief</div>
|
|
||||||
</td>
|
|
||||||
<!--END PROJECT_BRIEF-->
|
|
||||||
<!--END !PROJECT_NAME-->
|
|
||||||
<!--BEGIN DISABLE_INDEX-->
|
|
||||||
<!--BEGIN SEARCHENGINE-->
|
|
||||||
<td>$searchbox</td>
|
|
||||||
<!--END SEARCHENGINE-->
|
|
||||||
<!--END DISABLE_INDEX-->
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<!--END TITLEAREA-->
|
|
||||||
<!-- end header part -->
|
|
22
third_party/libosmium/doc/osmium.css
vendored
22
third_party/libosmium/doc/osmium.css
vendored
@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
body {
|
|
||||||
font-family: "Droid Sans",Helvetica,Arial,sans-serif;
|
|
||||||
background-color: #ffffff;
|
|
||||||
color: #202060;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabs, .tabs2, .tabs3, .navpath ul, .tablist li {
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabs, .tabs2, .tabs3 {
|
|
||||||
border-top: 1px solid #202060;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.contents {
|
|
||||||
margin: 0px;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-left: 12px;
|
|
||||||
padding-right: 8px;
|
|
||||||
}
|
|
||||||
|
|
92
third_party/libosmium/examples/CMakeLists.txt
vendored
92
third_party/libosmium/examples/CMakeLists.txt
vendored
@ -1,92 +0,0 @@
|
|||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# CMake Config
|
|
||||||
#
|
|
||||||
# Libosmium examples
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
message(STATUS "Configuring examples")
|
|
||||||
|
|
||||||
set(EXAMPLES
|
|
||||||
area_test
|
|
||||||
convert
|
|
||||||
count
|
|
||||||
create_node_cache
|
|
||||||
debug
|
|
||||||
filter_discussions
|
|
||||||
index
|
|
||||||
read
|
|
||||||
serdump
|
|
||||||
use_node_cache
|
|
||||||
CACHE STRING "Example programs"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Examples depending on wingetopt
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
set(GETOPT_EXAMPLES area_test convert serdump)
|
|
||||||
if(NOT GETOPT_MISSING)
|
|
||||||
foreach(example ${GETOPT_EXAMPLES})
|
|
||||||
list(APPEND EXAMPLE_LIBS_${example} ${GETOPT_LIBRARY})
|
|
||||||
endforeach()
|
|
||||||
else()
|
|
||||||
message(STATUS "Configuring examples - Skipping examples because on Visual Studio the wingetopt library is needed and was not found:")
|
|
||||||
foreach(example ${GETOPT_EXAMPLES})
|
|
||||||
message(STATUS " - osmium_${example}")
|
|
||||||
list(REMOVE_ITEM EXAMPLES ${example})
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Examples depending on SparseHash
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
if(NOT SPARSEHASH_FOUND)
|
|
||||||
list(REMOVE_ITEM EXAMPLES area_test)
|
|
||||||
message(STATUS "Configuring examples - Skipping examples because Google SparseHash not found:")
|
|
||||||
message(STATUS " - osmium_area_test")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Examples depending on Boost Program Options
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
unset(Boost_LIBRARIES)
|
|
||||||
unset(Boost_FOUND)
|
|
||||||
find_package(Boost 1.38 COMPONENTS program_options)
|
|
||||||
|
|
||||||
if(Boost_PROGRAM_OPTIONS_FOUND)
|
|
||||||
list(APPEND EXAMPLE_LIBS_index ${Boost_PROGRAM_OPTIONS_LIBRARY})
|
|
||||||
else()
|
|
||||||
list(REMOVE_ITEM EXAMPLES index)
|
|
||||||
message(STATUS "Configuring examples - Skipping examples because Boost program_options not found:")
|
|
||||||
message(STATUS " - osmium_index")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# Configure examples
|
|
||||||
#
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
message(STATUS "Configuring examples - Building these examples:")
|
|
||||||
foreach(example ${EXAMPLES})
|
|
||||||
message(STATUS " - osmium_${example}")
|
|
||||||
add_executable(osmium_${example} "osmium_${example}.cpp")
|
|
||||||
target_link_libraries(osmium_${example} ${OSMIUM_IO_LIBRARIES} ${EXAMPLE_LIBS_${example}})
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
message(STATUS "Configuring examples - done")
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
|
136
third_party/libosmium/examples/osmium_area_test.cpp
vendored
136
third_party/libosmium/examples/osmium_area_test.cpp
vendored
@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
This is an example tool that creates multipolygons from OSM data
|
|
||||||
and dumps them to stdout.
|
|
||||||
|
|
||||||
The code in this example file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <getopt.h>
|
|
||||||
|
|
||||||
#include <osmium/area/assembler.hpp>
|
|
||||||
#include <osmium/area/multipolygon_collector.hpp>
|
|
||||||
#include <osmium/dynamic_handler.hpp>
|
|
||||||
#include <osmium/geom/wkt.hpp>
|
|
||||||
#include <osmium/handler/dump.hpp>
|
|
||||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
|
||||||
#include <osmium/index/map/dummy.hpp>
|
|
||||||
#include <osmium/index/map/sparse_mem_array.hpp>
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
#include <osmium/visitor.hpp>
|
|
||||||
|
|
||||||
typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> index_neg_type;
|
|
||||||
typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_pos_type;
|
|
||||||
typedef osmium::handler::NodeLocationsForWays<index_pos_type, index_neg_type> location_handler_type;
|
|
||||||
|
|
||||||
class WKTDump : public osmium::handler::Handler {
|
|
||||||
|
|
||||||
osmium::geom::WKTFactory<> m_factory ;
|
|
||||||
|
|
||||||
std::ostream& m_out;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
WKTDump(std::ostream& out) :
|
|
||||||
m_out(out) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void area(const osmium::Area& area) {
|
|
||||||
try {
|
|
||||||
m_out << m_factory.create_multipolygon(area) << "\n";
|
|
||||||
} catch (osmium::geometry_error& e) {
|
|
||||||
m_out << "GEOMETRY ERROR: " << e.what() << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class WKTDump
|
|
||||||
|
|
||||||
void print_help() {
|
|
||||||
std::cout << "osmium_area_test [OPTIONS] OSMFILE\n\n"
|
|
||||||
<< "Read OSMFILE and build multipolygons from it.\n"
|
|
||||||
<< "\nOptions:\n"
|
|
||||||
<< " -h, --help This help message\n"
|
|
||||||
<< " -w, --dump-wkt Dump area geometries as WKT\n"
|
|
||||||
<< " -o, --dump-objects Dump area objects\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
static struct option long_options[] = {
|
|
||||||
{"help", no_argument, 0, 'h'},
|
|
||||||
{"dump-wkt", no_argument, 0, 'w'},
|
|
||||||
{"dump-objects", no_argument, 0, 'o'},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
osmium::handler::DynamicHandler handler;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
int c = getopt_long(argc, argv, "hwo", long_options, 0);
|
|
||||||
if (c == -1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case 'h':
|
|
||||||
print_help();
|
|
||||||
exit(0);
|
|
||||||
case 'w':
|
|
||||||
handler.set<WKTDump>(std::cout);
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
handler.set<osmium::handler::Dump>(std::cout);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int remaining_args = argc - optind;
|
|
||||||
if (remaining_args != 1) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " [OPTIONS] OSMFILE\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::io::File infile(argv[optind]);
|
|
||||||
|
|
||||||
osmium::area::Assembler::config_type assembler_config;
|
|
||||||
osmium::area::MultipolygonCollector<osmium::area::Assembler> collector(assembler_config);
|
|
||||||
|
|
||||||
std::cout << "Pass 1...\n";
|
|
||||||
osmium::io::Reader reader1(infile, osmium::osm_entity_bits::relation);
|
|
||||||
collector.read_relations(reader1);
|
|
||||||
reader1.close();
|
|
||||||
std::cout << "Pass 1 done\n";
|
|
||||||
|
|
||||||
std::cout << "Memory:\n";
|
|
||||||
collector.used_memory();
|
|
||||||
|
|
||||||
index_pos_type index_pos;
|
|
||||||
index_neg_type index_neg;
|
|
||||||
location_handler_type location_handler(index_pos, index_neg);
|
|
||||||
location_handler.ignore_errors(); // XXX
|
|
||||||
|
|
||||||
std::cout << "Pass 2...\n";
|
|
||||||
osmium::io::Reader reader2(infile);
|
|
||||||
osmium::apply(reader2, location_handler, collector.handler([&handler](osmium::memory::Buffer&& buffer) {
|
|
||||||
osmium::apply(buffer, handler);
|
|
||||||
}));
|
|
||||||
reader2.close();
|
|
||||||
std::cout << "Pass 2 done\n";
|
|
||||||
|
|
||||||
std::cout << "Memory:\n";
|
|
||||||
collector.used_memory();
|
|
||||||
|
|
||||||
std::vector<const osmium::Relation*> incomplete_relations = collector.get_incomplete_relations();
|
|
||||||
if (!incomplete_relations.empty()) {
|
|
||||||
std::cerr << "Warning! Some member ways missing for these multipolygon relations:";
|
|
||||||
for (const auto* relation : incomplete_relations) {
|
|
||||||
std::cerr << " " << relation->id();
|
|
||||||
}
|
|
||||||
std::cerr << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
111
third_party/libosmium/examples/osmium_convert.cpp
vendored
111
third_party/libosmium/examples/osmium_convert.cpp
vendored
@ -1,111 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Convert OSM files from one format into another.
|
|
||||||
|
|
||||||
The code in this example file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <getopt.h>
|
|
||||||
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
|
|
||||||
#include <osmium/io/any_output.hpp>
|
|
||||||
|
|
||||||
void print_help() {
|
|
||||||
std::cout << "osmium_convert [OPTIONS] [INFILE [OUTFILE]]\n\n" \
|
|
||||||
<< "If INFILE or OUTFILE is not given stdin/stdout is assumed.\n" \
|
|
||||||
<< "File format is autodetected from file name suffix.\n" \
|
|
||||||
<< "Use -f and -t options to force file format.\n" \
|
|
||||||
<< "\nFile types:\n" \
|
|
||||||
<< " osm normal OSM file\n" \
|
|
||||||
<< " osc OSM change file\n" \
|
|
||||||
<< " osh OSM file with history information\n" \
|
|
||||||
<< "\nFile format:\n" \
|
|
||||||
<< " (default) XML encoding\n" \
|
|
||||||
<< " pbf binary PBF encoding\n" \
|
|
||||||
<< " opl OPL encoding\n" \
|
|
||||||
<< "\nFile compression\n" \
|
|
||||||
<< " gz compressed with gzip\n" \
|
|
||||||
<< " bz2 compressed with bzip2\n" \
|
|
||||||
<< "\nOptions:\n" \
|
|
||||||
<< " -h, --help This help message\n" \
|
|
||||||
<< " -f, --from-format=FORMAT Input format\n" \
|
|
||||||
<< " -t, --to-format=FORMAT Output format\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
static struct option long_options[] = {
|
|
||||||
{"help", no_argument, 0, 'h'},
|
|
||||||
{"from-format", required_argument, 0, 'f'},
|
|
||||||
{"to-format", required_argument, 0, 't'},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string input_format;
|
|
||||||
std::string output_format;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
int c = getopt_long(argc, argv, "dhf:t:", long_options, 0);
|
|
||||||
if (c == -1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case 'h':
|
|
||||||
print_help();
|
|
||||||
exit(0);
|
|
||||||
case 'f':
|
|
||||||
input_format = optarg;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
output_format = optarg;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string input;
|
|
||||||
std::string output;
|
|
||||||
int remaining_args = argc - optind;
|
|
||||||
if (remaining_args > 2) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " [OPTIONS] [INFILE [OUTFILE]]" << std::endl;
|
|
||||||
exit(1);
|
|
||||||
} else if (remaining_args == 2) {
|
|
||||||
input = argv[optind];
|
|
||||||
output = argv[optind+1];
|
|
||||||
} else if (remaining_args == 1) {
|
|
||||||
input = argv[optind];
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::io::File infile(input, input_format);
|
|
||||||
|
|
||||||
osmium::io::File outfile(output, output_format);
|
|
||||||
|
|
||||||
if (infile.has_multiple_object_versions() && !outfile.has_multiple_object_versions()) {
|
|
||||||
std::cerr << "Warning! You are converting from an OSM file with (potentially) several versions of the same object to one that is not marked as such.\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int exit_code = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
osmium::io::Reader reader(infile);
|
|
||||||
osmium::io::Header header = reader.header();
|
|
||||||
header.set("generator", "osmium_convert");
|
|
||||||
|
|
||||||
osmium::io::Writer writer(outfile, header, osmium::io::overwrite::allow);
|
|
||||||
while (osmium::memory::Buffer buffer = reader.read()) {
|
|
||||||
writer(std::move(buffer));
|
|
||||||
}
|
|
||||||
writer.close();
|
|
||||||
reader.close();
|
|
||||||
} catch (std::exception& e) {
|
|
||||||
std::cerr << e.what() << "\n";
|
|
||||||
exit_code = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return exit_code;
|
|
||||||
}
|
|
||||||
|
|
56
third_party/libosmium/examples/osmium_count.cpp
vendored
56
third_party/libosmium/examples/osmium_count.cpp
vendored
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
This is a small tool that counts the number of nodes, ways, and relations in
|
|
||||||
the input file.
|
|
||||||
|
|
||||||
The code in this example file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
#include <osmium/handler.hpp>
|
|
||||||
#include <osmium/visitor.hpp>
|
|
||||||
|
|
||||||
struct CountHandler : public osmium::handler::Handler {
|
|
||||||
|
|
||||||
uint64_t nodes = 0;
|
|
||||||
uint64_t ways = 0;
|
|
||||||
uint64_t relations = 0;
|
|
||||||
|
|
||||||
void node(osmium::Node&) {
|
|
||||||
++nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void way(osmium::Way&) {
|
|
||||||
++ways;
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation(osmium::Relation&) {
|
|
||||||
++relations;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::io::File infile(argv[1]);
|
|
||||||
osmium::io::Reader reader(infile);
|
|
||||||
|
|
||||||
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";
|
|
||||||
}
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
This reads an OSM file and writes out the node locations to a cache
|
|
||||||
file.
|
|
||||||
|
|
||||||
The code in this example file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
|
|
||||||
#include <osmium/index/map/dummy.hpp>
|
|
||||||
#include <osmium/index/map/dense_mmap_array.hpp>
|
|
||||||
#include <osmium/index/map/dense_file_array.hpp>
|
|
||||||
|
|
||||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
|
||||||
#include <osmium/visitor.hpp>
|
|
||||||
|
|
||||||
typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> index_neg_type;
|
|
||||||
//typedef osmium::index::map::DenseMmapArray<osmium::unsigned_object_id_type, osmium::Location> index_pos_type;
|
|
||||||
typedef osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, osmium::Location> index_pos_type;
|
|
||||||
|
|
||||||
typedef osmium::handler::NodeLocationsForWays<index_pos_type, index_neg_type> location_handler_type;
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
if (argc != 3) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " OSM_FILE CACHE_FILE\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string input_filename(argv[1]);
|
|
||||||
osmium::io::Reader reader(input_filename, osmium::osm_entity_bits::node);
|
|
||||||
|
|
||||||
int fd = open(argv[2], O_RDWR | O_CREAT, 0666);
|
|
||||||
if (fd == -1) {
|
|
||||||
std::cerr << "Can not open node cache file '" << argv[2] << "': " << strerror(errno) << "\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
index_pos_type index_pos {fd};
|
|
||||||
index_neg_type index_neg;
|
|
||||||
location_handler_type location_handler(index_pos, index_neg);
|
|
||||||
location_handler.ignore_errors();
|
|
||||||
|
|
||||||
osmium::apply(reader, location_handler);
|
|
||||||
reader.close();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
50
third_party/libosmium/examples/osmium_debug.cpp
vendored
50
third_party/libosmium/examples/osmium_debug.cpp
vendored
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
This is a small tool to dump the contents of the input file.
|
|
||||||
|
|
||||||
The code in this example file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <osmium/handler/dump.hpp>
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
std::ios_base::sync_with_stdio(false);
|
|
||||||
|
|
||||||
if (argc < 2 || argc > 3) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " OSMFILE [TYPES]\n";
|
|
||||||
std::cerr << "TYPES can be any combination of 'n', 'w', 'r', and 'c' to indicate what types of OSM entities you want (default: all).\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::osm_entity_bits::type read_types = osmium::osm_entity_bits::all;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::io::Reader reader(argv[1], read_types);
|
|
||||||
osmium::io::Header header = reader.header();
|
|
||||||
|
|
||||||
std::cout << "HEADER:\n generator=" << header.get("generator") << "\n";
|
|
||||||
|
|
||||||
for (auto& bbox : header.boxes()) {
|
|
||||||
std::cout << " bbox=" << bbox << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::handler::Dump dump(std::cout);
|
|
||||||
while (osmium::memory::Buffer buffer = reader.read()) {
|
|
||||||
osmium::apply(buffer, dump);
|
|
||||||
}
|
|
||||||
|
|
||||||
reader.close();
|
|
||||||
}
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Read OSM changesets with discussions from a changeset dump like the one
|
|
||||||
you get from http://planet.osm.org/planet/discussions-latest.osm.bz2
|
|
||||||
and write out only those changesets which have discussions (ie comments).
|
|
||||||
|
|
||||||
The code in this example file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm> // for std::copy_if
|
|
||||||
#include <iostream> // for std::cout, std::cerr
|
|
||||||
|
|
||||||
// we want to read OSM files in XML format
|
|
||||||
// (other formats don't support full changesets, so only XML is needed here)
|
|
||||||
#include <osmium/io/xml_input.hpp>
|
|
||||||
#include <osmium/io/input_iterator.hpp>
|
|
||||||
|
|
||||||
// we want to write OSM files in XML format
|
|
||||||
#include <osmium/io/xml_output.hpp>
|
|
||||||
#include <osmium/io/output_iterator.hpp>
|
|
||||||
|
|
||||||
// we want to support any compressioon (.gz2 and .bz2)
|
|
||||||
#include <osmium/io/any_compression.hpp>
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
if (argc != 3) {
|
|
||||||
std::cout << "Usage: " << argv[0] << " INFILE OUTFILE\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The input file, deduce file format from file suffix
|
|
||||||
osmium::io::File infile(argv[1]);
|
|
||||||
|
|
||||||
// The output file, force class XML OSM file format
|
|
||||||
osmium::io::File outfile(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(infile, osmium::osm_entity_bits::changeset);
|
|
||||||
|
|
||||||
// Get the header from the input file
|
|
||||||
osmium::io::Header header = reader.header();
|
|
||||||
|
|
||||||
// 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(outfile, 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 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;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
237
third_party/libosmium/examples/osmium_index.cpp
vendored
237
third_party/libosmium/examples/osmium_index.cpp
vendored
@ -1,237 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Example program to look at Osmium indexes on disk.
|
|
||||||
|
|
||||||
The code in this example file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
|
||||||
|
|
||||||
#include <osmium/index/map/dense_file_array.hpp>
|
|
||||||
#include <osmium/index/map/sparse_file_array.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/types.hpp>
|
|
||||||
|
|
||||||
template <typename TKey, typename TValue>
|
|
||||||
class IndexSearch {
|
|
||||||
|
|
||||||
typedef typename osmium::index::map::DenseFileArray<TKey, TValue> dense_index_type;
|
|
||||||
typedef typename osmium::index::map::SparseFileArray<TKey, TValue> sparse_index_type;
|
|
||||||
|
|
||||||
int m_fd;
|
|
||||||
bool m_dense_format;
|
|
||||||
|
|
||||||
void dump_dense() {
|
|
||||||
dense_index_type index(m_fd);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < index.size(); ++i) {
|
|
||||||
if (index.get(i) != TValue()) {
|
|
||||||
std::cout << i << " " << index.get(i) << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_sparse() {
|
|
||||||
sparse_index_type index(m_fd);
|
|
||||||
|
|
||||||
for (auto& element : index) {
|
|
||||||
std::cout << element.first << " " << element.second << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool search_dense(TKey key) {
|
|
||||||
dense_index_type index(m_fd);
|
|
||||||
|
|
||||||
try {
|
|
||||||
TValue value = index.get(key);
|
|
||||||
std::cout << key << " " << value << std::endl;
|
|
||||||
} catch (...) {
|
|
||||||
std::cout << key << " not found" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool search_sparse(TKey key) {
|
|
||||||
typedef typename sparse_index_type::element_type element_type;
|
|
||||||
sparse_index_type index(m_fd);
|
|
||||||
|
|
||||||
element_type elem {key, TValue()};
|
|
||||||
auto positions = std::equal_range(index.begin(), index.end(), elem, [](const element_type& lhs, const element_type& rhs) {
|
|
||||||
return lhs.first < rhs.first;
|
|
||||||
});
|
|
||||||
if (positions.first == positions.second) {
|
|
||||||
std::cout << key << " not found" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& it = positions.first; it != positions.second; ++it) {
|
|
||||||
std::cout << it->first << " " << it->second << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
IndexSearch(int fd, bool dense_format) :
|
|
||||||
m_fd(fd),
|
|
||||||
m_dense_format(dense_format) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump() {
|
|
||||||
if (m_dense_format) {
|
|
||||||
dump_dense();
|
|
||||||
} else {
|
|
||||||
dump_sparse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool search(TKey key) {
|
|
||||||
if (m_dense_format) {
|
|
||||||
return search_dense(key);
|
|
||||||
} else {
|
|
||||||
return search_sparse(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool search(std::vector<TKey> keys) {
|
|
||||||
bool found_all = true;
|
|
||||||
|
|
||||||
for (const auto key : keys) {
|
|
||||||
if (!search(key)) {
|
|
||||||
found_all = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found_all;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class IndexSearch
|
|
||||||
|
|
||||||
enum return_code : int {
|
|
||||||
okay = 0,
|
|
||||||
not_found = 1,
|
|
||||||
error = 2,
|
|
||||||
fatal = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace po = boost::program_options;
|
|
||||||
|
|
||||||
class Options {
|
|
||||||
|
|
||||||
po::variables_map vm;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Options(int argc, char* argv[]) {
|
|
||||||
try {
|
|
||||||
po::options_description desc("Allowed options");
|
|
||||||
desc.add_options()
|
|
||||||
("help,h", "Print this help message")
|
|
||||||
("array,a", po::value<std::string>(), "Read given index file in array format")
|
|
||||||
("list,l", po::value<std::string>(), "Read given index file in list format")
|
|
||||||
("dump,d", "Dump contents of index file to STDOUT")
|
|
||||||
("search,s", po::value<std::vector<osmium::unsigned_object_id_type>>(), "Search for given id (Option can appear multiple times)")
|
|
||||||
("type,t", po::value<std::string>(), "Type of value ('location' or 'offset')")
|
|
||||||
;
|
|
||||||
|
|
||||||
po::store(po::parse_command_line(argc, argv, desc), vm);
|
|
||||||
po::notify(vm);
|
|
||||||
|
|
||||||
if (vm.count("help")) {
|
|
||||||
std::cout << desc << "\n";
|
|
||||||
exit(return_code::okay);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vm.count("array") && vm.count("list")) {
|
|
||||||
std::cerr << "Only option --array or --list allowed." << std::endl;
|
|
||||||
exit(return_code::fatal);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vm.count("array") && !vm.count("list")) {
|
|
||||||
std::cerr << "Need one of option --array or --list." << std::endl;
|
|
||||||
exit(return_code::fatal);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vm.count("type")) {
|
|
||||||
std::cerr << "Need --type argument." << std::endl;
|
|
||||||
exit(return_code::fatal);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& type = vm["type"].as<std::string>();
|
|
||||||
if (type != "location" && type != "offset") {
|
|
||||||
std::cerr << "Unknown type '" << type << "'. Must be 'location' or 'offset'." << std::endl;
|
|
||||||
exit(return_code::fatal);
|
|
||||||
}
|
|
||||||
} catch (boost::program_options::error& e) {
|
|
||||||
std::cerr << "Error parsing command line: " << e.what() << std::endl;
|
|
||||||
exit(return_code::fatal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& filename() const {
|
|
||||||
if (vm.count("array")) {
|
|
||||||
return vm["array"].as<std::string>();
|
|
||||||
} else {
|
|
||||||
return vm["list"].as<std::string>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dense_format() const {
|
|
||||||
return vm.count("array") != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool do_dump() const {
|
|
||||||
return vm.count("dump") != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<osmium::unsigned_object_id_type> search_keys() const {
|
|
||||||
return vm["search"].as<std::vector<osmium::unsigned_object_id_type>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool type_is(const char* type) const {
|
|
||||||
return vm["type"].as<std::string>() == type;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class Options
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
std::ios_base::sync_with_stdio(false);
|
|
||||||
|
|
||||||
Options options(argc, argv);
|
|
||||||
|
|
||||||
std::cout << std::fixed << std::setprecision(7);
|
|
||||||
int fd = open(options.filename().c_str(), O_RDWR);
|
|
||||||
|
|
||||||
bool result_okay = true;
|
|
||||||
|
|
||||||
if (options.type_is("location")) {
|
|
||||||
IndexSearch<osmium::unsigned_object_id_type, osmium::Location> is(fd, options.dense_format());
|
|
||||||
|
|
||||||
if (options.do_dump()) {
|
|
||||||
is.dump();
|
|
||||||
} else {
|
|
||||||
result_okay = is.search(options.search_keys());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
IndexSearch<osmium::unsigned_object_id_type, size_t> is(fd, options.dense_format());
|
|
||||||
|
|
||||||
if (options.do_dump()) {
|
|
||||||
is.dump();
|
|
||||||
} else {
|
|
||||||
result_okay = is.search(options.search_keys());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(result_okay ? return_code::okay : return_code::not_found);
|
|
||||||
}
|
|
||||||
|
|
30
third_party/libosmium/examples/osmium_read.cpp
vendored
30
third_party/libosmium/examples/osmium_read.cpp
vendored
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
This is a small tool that reads and discards the contents of the input file.
|
|
||||||
(Used for timing.)
|
|
||||||
|
|
||||||
The code in this example file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::io::File infile(argv[1]);
|
|
||||||
osmium::io::Reader reader(infile);
|
|
||||||
|
|
||||||
while (osmium::memory::Buffer buffer = reader.read()) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
reader.close();
|
|
||||||
}
|
|
||||||
|
|
206
third_party/libosmium/examples/osmium_serdump.cpp
vendored
206
third_party/libosmium/examples/osmium_serdump.cpp
vendored
@ -1,206 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
This is a small tool to dump the contents of the input file
|
|
||||||
in serialized format to stdout.
|
|
||||||
|
|
||||||
The code in this example file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
# include <direct.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
#include <osmium/handler/disk_store.hpp>
|
|
||||||
#include <osmium/handler/object_relations.hpp>
|
|
||||||
|
|
||||||
#include <osmium/index/map/sparse_mem_array.hpp>
|
|
||||||
#include <osmium/index/multimap/sparse_mem_multimap.hpp>
|
|
||||||
#include <osmium/index/multimap/sparse_mem_array.hpp>
|
|
||||||
#include <osmium/index/multimap/hybrid.hpp>
|
|
||||||
|
|
||||||
// ==============================================================================
|
|
||||||
// Choose the following depending on the size of the input OSM files:
|
|
||||||
// ==============================================================================
|
|
||||||
// for smaller OSM files (extracts)
|
|
||||||
typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, size_t> offset_index_type;
|
|
||||||
//typedef osmium::index::map::SparseMapMmap<osmium::unsigned_object_id_type, size_t> offset_index_type;
|
|
||||||
//typedef osmium::index::map::SparseMapFile<osmium::unsigned_object_id_type, size_t> offset_index_type;
|
|
||||||
|
|
||||||
typedef osmium::index::multimap::SparseMemArray<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type> map_type;
|
|
||||||
//typedef osmium::index::multimap::SparseMemMultimap<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type> map_type;
|
|
||||||
//typedef osmium::index::multimap::Hybrid<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type> map_type;
|
|
||||||
|
|
||||||
// ==============================================================================
|
|
||||||
// for very large OSM files (planet)
|
|
||||||
//typedef osmium::index::map::DenseMmapArray<osmium::unsigned_object_id_type, size_t> offset_index_type;
|
|
||||||
// ==============================================================================
|
|
||||||
|
|
||||||
void print_help() {
|
|
||||||
std::cout << "osmium_serdump OSMFILE DIR\n" \
|
|
||||||
<< "Serialize content of OSMFILE into data file in DIR.\n" \
|
|
||||||
<< "\nOptions:\n" \
|
|
||||||
<< " -h, --help This help message\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
std::ios_base::sync_with_stdio(false);
|
|
||||||
|
|
||||||
static struct option long_options[] = {
|
|
||||||
{"help", no_argument, 0, 'h'},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
int c = getopt_long(argc, argv, "h", long_options, 0);
|
|
||||||
if (c == -1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case 'h':
|
|
||||||
print_help();
|
|
||||||
exit(0);
|
|
||||||
default:
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int remaining_args = argc - optind;
|
|
||||||
|
|
||||||
if (remaining_args != 2) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " OSMFILE DIR\n";
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string dir(argv[optind+1]);
|
|
||||||
#ifndef _WIN32
|
|
||||||
int result = ::mkdir(dir.c_str(), 0777);
|
|
||||||
#else
|
|
||||||
int result = mkdir(dir.c_str());
|
|
||||||
#endif
|
|
||||||
if (result == -1 && errno != EEXIST) {
|
|
||||||
std::cerr << "Problem creating directory '" << dir << "': " << strerror(errno) << "\n";
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string data_file(dir + "/data.osm.ser");
|
|
||||||
int data_fd = ::open(data_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
|
||||||
if (data_fd < 0) {
|
|
||||||
std::cerr << "Can't open data file '" << data_file << "': " << strerror(errno) << "\n";
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
offset_index_type node_index;
|
|
||||||
offset_index_type way_index;
|
|
||||||
offset_index_type relation_index;
|
|
||||||
|
|
||||||
osmium::handler::DiskStore disk_store_handler(data_fd, node_index, way_index, relation_index);
|
|
||||||
|
|
||||||
map_type map_node2way;
|
|
||||||
map_type map_node2relation;
|
|
||||||
map_type map_way2relation;
|
|
||||||
map_type map_relation2relation;
|
|
||||||
|
|
||||||
osmium::handler::ObjectRelations object_relations_handler(map_node2way, map_node2relation, map_way2relation, map_relation2relation);
|
|
||||||
|
|
||||||
osmium::io::Reader reader(argv[1]);
|
|
||||||
|
|
||||||
while (osmium::memory::Buffer buffer = reader.read()) {
|
|
||||||
disk_store_handler(buffer); // XXX
|
|
||||||
osmium::apply(buffer, object_relations_handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
reader.close();
|
|
||||||
|
|
||||||
{
|
|
||||||
std::string index_file(dir + "/nodes.idx");
|
|
||||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
|
||||||
if (fd < 0) {
|
|
||||||
std::cerr << "Can't open nodes index file '" << index_file << "': " << strerror(errno) << "\n";
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
node_index.dump_as_list(fd);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::string index_file(dir + "/ways.idx");
|
|
||||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
|
||||||
if (fd < 0) {
|
|
||||||
std::cerr << "Can't open ways index file '" << index_file << "': " << strerror(errno) << "\n";
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
way_index.dump_as_list(fd);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::string index_file(dir + "/relations.idx");
|
|
||||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
|
||||||
if (fd < 0) {
|
|
||||||
std::cerr << "Can't open relations index file '" << index_file << "': " << strerror(errno) << "\n";
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
relation_index.dump_as_list(fd);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
map_node2way.sort();
|
|
||||||
std::string index_file(dir + "/node2way.map");
|
|
||||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
|
||||||
if (fd < 0) {
|
|
||||||
std::cerr << "Can't open node->way map file '" << index_file << "': " << strerror(errno) << "\n";
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
map_node2way.dump_as_list(fd);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
map_node2relation.sort();
|
|
||||||
std::string index_file(dir + "/node2rel.map");
|
|
||||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
|
||||||
if (fd < 0) {
|
|
||||||
std::cerr << "Can't open node->rel map file '" << index_file << "': " << strerror(errno) << "\n";
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
map_node2relation.dump_as_list(fd);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
map_way2relation.sort();
|
|
||||||
std::string index_file(dir + "/way2rel.map");
|
|
||||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
|
||||||
if (fd < 0) {
|
|
||||||
std::cerr << "Can't open way->rel map file '" << index_file << "': " << strerror(errno) << "\n";
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
map_way2relation.dump_as_list(fd);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
map_relation2relation.sort();
|
|
||||||
std::string index_file(dir + "/rel2rel.map");
|
|
||||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
|
||||||
if (fd < 0) {
|
|
||||||
std::cerr << "Can't open rel->rel map file '" << index_file << "': " << strerror(errno) << "\n";
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
map_relation2relation.dump_as_list(fd);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
This reads ways from an OSM file and writes out the node locations
|
|
||||||
it got from a node cache generated with osmium_create_node_cache.
|
|
||||||
|
|
||||||
The code in this example file is released into the Public Domain.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <osmium/io/any_input.hpp>
|
|
||||||
|
|
||||||
#include <osmium/index/map/dummy.hpp>
|
|
||||||
#include <osmium/index/map/dense_file_array.hpp>
|
|
||||||
#include <osmium/index/map/dense_mmap_array.hpp>
|
|
||||||
|
|
||||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
|
||||||
#include <osmium/visitor.hpp>
|
|
||||||
|
|
||||||
typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> index_neg_type;
|
|
||||||
//typedef osmium::index::map::DenseMmapArray<osmium::unsigned_object_id_type, osmium::Location> index_pos_type;
|
|
||||||
typedef osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, osmium::Location> index_pos_type;
|
|
||||||
|
|
||||||
typedef osmium::handler::NodeLocationsForWays<index_pos_type, index_neg_type> location_handler_type;
|
|
||||||
|
|
||||||
class MyHandler : public osmium::handler::Handler {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void way(osmium::Way& way) {
|
|
||||||
for (auto& nr : way.nodes()) {
|
|
||||||
std::cout << nr << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class MyHandler
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
if (argc != 3) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " OSM_FILE CACHE_FILE\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string input_filename(argv[1]);
|
|
||||||
osmium::io::Reader reader(input_filename, osmium::osm_entity_bits::way);
|
|
||||||
|
|
||||||
int fd = open(argv[2], O_RDWR);
|
|
||||||
if (fd == -1) {
|
|
||||||
std::cerr << "Can not open node cache file '" << argv[2] << "': " << strerror(errno) << "\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
index_pos_type index_pos {fd};
|
|
||||||
index_neg_type index_neg;
|
|
||||||
location_handler_type location_handler(index_pos, index_neg);
|
|
||||||
location_handler.ignore_errors();
|
|
||||||
|
|
||||||
MyHandler handler;
|
|
||||||
osmium::apply(reader, location_handler, handler);
|
|
||||||
reader.close();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
406
third_party/libosmium/include/gdalcpp.hpp
vendored
406
third_party/libosmium/include/gdalcpp.hpp
vendored
@ -1,406 +0,0 @@
|
|||||||
#ifndef GDALCPP_HPP
|
|
||||||
#define GDALCPP_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
C++11 wrapper classes for GDAL/OGR.
|
|
||||||
|
|
||||||
Version 1.1.1
|
|
||||||
|
|
||||||
https://github.com/joto/gdalcpp
|
|
||||||
|
|
||||||
Copyright 2015 Jochen Topf <jochen@topf.org>
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <memory>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <gdal_priv.h>
|
|
||||||
#include <gdal_version.h>
|
|
||||||
#include <ogr_api.h>
|
|
||||||
#include <ogrsf_frmts.h>
|
|
||||||
|
|
||||||
namespace gdalcpp {
|
|
||||||
|
|
||||||
#if GDAL_VERSION_MAJOR >= 2
|
|
||||||
using gdal_driver_type = GDALDriver;
|
|
||||||
using gdal_dataset_type = GDALDataset;
|
|
||||||
#else
|
|
||||||
using gdal_driver_type = OGRSFDriver;
|
|
||||||
using gdal_dataset_type = OGRDataSource;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception thrown for all errors in this class.
|
|
||||||
*/
|
|
||||||
class gdal_error : public std::runtime_error {
|
|
||||||
|
|
||||||
std::string m_driver;
|
|
||||||
std::string m_dataset;
|
|
||||||
std::string m_layer;
|
|
||||||
std::string m_field;
|
|
||||||
OGRErr m_error;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
gdal_error(const std::string& message,
|
|
||||||
OGRErr error,
|
|
||||||
const std::string& driver = "",
|
|
||||||
const std::string& dataset = "",
|
|
||||||
const std::string& layer = "",
|
|
||||||
const std::string& field = "") :
|
|
||||||
std::runtime_error(message),
|
|
||||||
m_driver(driver),
|
|
||||||
m_dataset(dataset),
|
|
||||||
m_layer(layer),
|
|
||||||
m_field(field),
|
|
||||||
m_error(error) {
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& driver() const {
|
|
||||||
return m_driver;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& dataset() const {
|
|
||||||
return m_dataset;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& layer() const {
|
|
||||||
return m_layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& field() const {
|
|
||||||
return m_field;
|
|
||||||
}
|
|
||||||
|
|
||||||
OGRErr error() const {
|
|
||||||
return m_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class gdal_error
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
struct init_wrapper {
|
|
||||||
init_wrapper() { OGRRegisterAll(); }
|
|
||||||
~init_wrapper() { OGRCleanupAll(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct init_library {
|
|
||||||
init_library() {
|
|
||||||
static init_wrapper iw;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Driver : private init_library {
|
|
||||||
|
|
||||||
gdal_driver_type* m_driver;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Driver(const std::string& driver_name) :
|
|
||||||
init_library(),
|
|
||||||
#if GDAL_VERSION_MAJOR >= 2
|
|
||||||
m_driver(GetGDALDriverManager()->GetDriverByName(driver_name.c_str())) {
|
|
||||||
#else
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gdal_driver_type& get() const {
|
|
||||||
return *m_driver;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct Driver
|
|
||||||
|
|
||||||
struct Options {
|
|
||||||
|
|
||||||
std::vector<std::string> m_options;
|
|
||||||
std::unique_ptr<const char*[]> m_ptrs;
|
|
||||||
|
|
||||||
Options(const std::vector<std::string>& options) :
|
|
||||||
m_options(options),
|
|
||||||
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 {
|
|
||||||
return const_cast<char**>(m_ptrs.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct Options
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
class SRS {
|
|
||||||
|
|
||||||
OGRSpatialReference m_spatial_reference;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
SRS() :
|
|
||||||
m_spatial_reference() {
|
|
||||||
auto result = m_spatial_reference.SetWellKnownGeogCS("WGS84");
|
|
||||||
if (result != OGRERR_NONE) {
|
|
||||||
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);
|
|
||||||
if (result != OGRERR_NONE) {
|
|
||||||
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);
|
|
||||||
if (result != OGRERR_NONE) {
|
|
||||||
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());
|
|
||||||
if (result != OGRERR_NONE) {
|
|
||||||
throw gdal_error(std::string("can not initialize spatial reference system '") + name + "'", result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit SRS(const OGRSpatialReference& spatial_reference) :
|
|
||||||
m_spatial_reference(spatial_reference) {
|
|
||||||
}
|
|
||||||
|
|
||||||
OGRSpatialReference& get() {
|
|
||||||
return m_spatial_reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
const OGRSpatialReference& get() const {
|
|
||||||
return m_spatial_reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class SRS
|
|
||||||
|
|
||||||
class Dataset {
|
|
||||||
|
|
||||||
struct gdal_dataset_deleter {
|
|
||||||
|
|
||||||
void operator()(gdal_dataset_type* ds) {
|
|
||||||
#if GDAL_VERSION_MAJOR >= 2
|
|
||||||
GDALClose(ds);
|
|
||||||
#else
|
|
||||||
OGRDataSource::DestroyDataSource(ds);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct gdal_dataset_deleter
|
|
||||||
|
|
||||||
std::string m_driver_name;
|
|
||||||
std::string m_dataset_name;
|
|
||||||
detail::Options m_options;
|
|
||||||
SRS m_srs;
|
|
||||||
std::unique_ptr<gdal_dataset_type, gdal_dataset_deleter> m_dataset;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Dataset(const std::string& driver_name, const std::string& dataset_name, const SRS& srs = SRS{}, const std::vector<std::string>& options = {}) :
|
|
||||||
m_driver_name(driver_name),
|
|
||||||
m_dataset_name(dataset_name),
|
|
||||||
m_options(options),
|
|
||||||
m_srs(srs),
|
|
||||||
#if GDAL_VERSION_MAJOR >= 2
|
|
||||||
m_dataset(detail::Driver(driver_name).get().Create(dataset_name.c_str(), 0, 0, 0, GDT_Unknown, m_options.get())) {
|
|
||||||
#else
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& driver_name() const {
|
|
||||||
return m_driver_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& dataset_name() const {
|
|
||||||
return m_dataset_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
gdal_dataset_type& get() const {
|
|
||||||
return *m_dataset;
|
|
||||||
}
|
|
||||||
|
|
||||||
SRS& srs() {
|
|
||||||
return m_srs;
|
|
||||||
}
|
|
||||||
|
|
||||||
void exec(const char* sql) {
|
|
||||||
auto result = m_dataset->ExecuteSQL(sql, nullptr, nullptr);
|
|
||||||
if (result) {
|
|
||||||
m_dataset->ReleaseResultSet(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void exec(const std::string& sql) {
|
|
||||||
exec(sql.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Dataset& start_transaction() {
|
|
||||||
#if GDAL_VERSION_MAJOR >= 2
|
|
||||||
m_dataset->StartTransaction();
|
|
||||||
#endif
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dataset& commit_transaction() {
|
|
||||||
#if GDAL_VERSION_MAJOR >= 2
|
|
||||||
m_dataset->CommitTransaction();
|
|
||||||
#endif
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class Dataset
|
|
||||||
|
|
||||||
class Layer {
|
|
||||||
|
|
||||||
detail::Options m_options;
|
|
||||||
Dataset& m_dataset;
|
|
||||||
OGRLayer* m_layer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Layer(Dataset& dataset, const std::string& layer_name, OGRwkbGeometryType type, const std::vector<std::string>& options = {}) :
|
|
||||||
m_options(options),
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OGRLayer& get() {
|
|
||||||
return *m_layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
const OGRLayer& get() const {
|
|
||||||
return *m_layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dataset& dataset() const {
|
|
||||||
return m_dataset;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* name() const {
|
|
||||||
return m_layer->GetName();
|
|
||||||
}
|
|
||||||
|
|
||||||
Layer& add_field(const std::string& field_name, OGRFieldType type, int width, int precision=0) {
|
|
||||||
OGRFieldDefn field(field_name.c_str(), type);
|
|
||||||
field.SetWidth(width);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Layer& start_transaction() {
|
|
||||||
OGRErr 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());
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Layer& commit_transaction() {
|
|
||||||
OGRErr 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());
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class Layer
|
|
||||||
|
|
||||||
class Feature {
|
|
||||||
|
|
||||||
Layer& m_layer;
|
|
||||||
OGRFeature m_feature;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Feature(Layer& layer, std::unique_ptr<OGRGeometry>&& geometry) :
|
|
||||||
m_layer(layer),
|
|
||||||
m_feature(m_layer.get().GetLayerDefn()) {
|
|
||||||
OGRErr 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_to_layer() {
|
|
||||||
OGRErr result = m_layer.get().CreateFeature(&m_feature);
|
|
||||||
if (result != OGRERR_NONE) {
|
|
||||||
throw gdal_error(std::string("creating feature in layer '") + m_layer.name() + "' failed", result, m_layer.dataset().driver_name(), m_layer.dataset().dataset_name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
Feature& set_field(int n, T&& arg) {
|
|
||||||
m_feature.SetField(n, std::forward<T>(arg));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
Feature& set_field(const char* name, T&& arg) {
|
|
||||||
m_feature.SetField(name, std::forward<T>(arg));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class Feature
|
|
||||||
|
|
||||||
} // namespace gdalcpp
|
|
||||||
|
|
||||||
#endif // GDALCPP_HPP
|
|
@ -1,787 +0,0 @@
|
|||||||
#ifndef OSMIUM_AREA_ASSEMBLER_HPP
|
|
||||||
#define OSMIUM_AREA_ASSEMBLER_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
#include <iterator>
|
|
||||||
#include <list>
|
|
||||||
#include <set>
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <osmium/builder/osm_object_builder.hpp>
|
|
||||||
#include <osmium/memory/buffer.hpp>
|
|
||||||
#include <osmium/osm/area.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/relation.hpp>
|
|
||||||
#include <osmium/tags/filter.hpp>
|
|
||||||
|
|
||||||
#include <osmium/area/detail/proto_ring.hpp>
|
|
||||||
#include <osmium/area/detail/node_ref_segment.hpp>
|
|
||||||
#include <osmium/area/detail/segment_list.hpp>
|
|
||||||
#include <osmium/area/problem_reporter.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace area {
|
|
||||||
|
|
||||||
using osmium::area::detail::ProtoRing;
|
|
||||||
|
|
||||||
struct AssemblerConfig {
|
|
||||||
|
|
||||||
osmium::area::ProblemReporter* problem_reporter;
|
|
||||||
|
|
||||||
// Enables debug output to stderr
|
|
||||||
bool debug;
|
|
||||||
|
|
||||||
explicit AssemblerConfig(osmium::area::ProblemReporter* pr = nullptr, bool d = false) :
|
|
||||||
problem_reporter(pr),
|
|
||||||
debug(d) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable or disable debug output to stderr. This is for Osmium
|
|
||||||
* developers only.
|
|
||||||
*/
|
|
||||||
void enable_debug_output(bool d = true) {
|
|
||||||
debug = d;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct AssemblerConfig
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assembles area objects from multipolygon relations and their
|
|
||||||
* members. This is called by the MultipolygonCollector object
|
|
||||||
* after all members have been collected.
|
|
||||||
*/
|
|
||||||
class Assembler {
|
|
||||||
|
|
||||||
const AssemblerConfig m_config;
|
|
||||||
|
|
||||||
// The way segments
|
|
||||||
osmium::area::detail::SegmentList m_segment_list;
|
|
||||||
|
|
||||||
// The rings we are building from the way segments
|
|
||||||
std::list<ProtoRing> m_rings;
|
|
||||||
|
|
||||||
std::vector<ProtoRing*> m_outer_rings;
|
|
||||||
std::vector<ProtoRing*> m_inner_rings;
|
|
||||||
|
|
||||||
int m_inner_outer_mismatches { 0 };
|
|
||||||
|
|
||||||
bool debug() const {
|
|
||||||
return m_config.debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the given NodeRefs have the same location.
|
|
||||||
* Uses the actual location for the test, not the id. If both
|
|
||||||
* have the same location, but not the same id, a problem
|
|
||||||
* point will be added to the list of problem points.
|
|
||||||
*/
|
|
||||||
bool has_same_location(const osmium::NodeRef& nr1, const osmium::NodeRef& nr2) {
|
|
||||||
if (nr1.location() != nr2.location()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (nr1.ref() != nr2.ref()) {
|
|
||||||
if (m_config.problem_reporter) {
|
|
||||||
m_config.problem_reporter->report_duplicate_node(nr1.ref(), nr2.ref(), nr1.location());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_tags_to_area(osmium::builder::AreaBuilder& builder, const osmium::Way& way) const {
|
|
||||||
osmium::builder::TagListBuilder tl_builder(builder.buffer(), &builder);
|
|
||||||
for (const osmium::Tag& tag : way.tags()) {
|
|
||||||
tl_builder.add_tag(tag.key(), tag.value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_common_tags(osmium::builder::TagListBuilder& tl_builder, std::set<const osmium::Way*>& ways) const {
|
|
||||||
std::map<std::string, size_t> counter;
|
|
||||||
for (const osmium::Way* way : ways) {
|
|
||||||
for (const auto& tag : way->tags()) {
|
|
||||||
std::string kv {tag.key()};
|
|
||||||
kv.append(1, '\0');
|
|
||||||
kv.append(tag.value());
|
|
||||||
++counter[kv];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t num_ways = ways.size();
|
|
||||||
for (const auto& t_c : counter) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " tag " << t_c.first << " is used " << t_c.second << " times in " << num_ways << " ways\n";
|
|
||||||
}
|
|
||||||
if (t_c.second == num_ways) {
|
|
||||||
size_t len = std::strlen(t_c.first.c_str());
|
|
||||||
tl_builder.add_tag(t_c.first.c_str(), t_c.first.c_str() + len + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MPFilter : public osmium::tags::KeyFilter {
|
|
||||||
|
|
||||||
MPFilter() : osmium::tags::KeyFilter(true) {
|
|
||||||
add(false, "type");
|
|
||||||
add(false, "created_by");
|
|
||||||
add(false, "source");
|
|
||||||
add(false, "note");
|
|
||||||
add(false, "test:id");
|
|
||||||
add(false, "test:section");
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct MPFilter
|
|
||||||
|
|
||||||
static MPFilter& filter() {
|
|
||||||
static MPFilter filter;
|
|
||||||
return filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_tags_to_area(osmium::builder::AreaBuilder& builder, const osmium::Relation& relation) const {
|
|
||||||
const auto count = std::count_if(relation.tags().begin(), relation.tags().end(), filter());
|
|
||||||
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " found " << count << " tags on relation (without ignored ones)\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count > 0) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " use tags from relation\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// write out all tags except type=*
|
|
||||||
osmium::builder::TagListBuilder tl_builder(builder.buffer(), &builder);
|
|
||||||
for (const osmium::Tag& tag : relation.tags()) {
|
|
||||||
if (strcmp(tag.key(), "type")) {
|
|
||||||
tl_builder.add_tag(tag.key(), tag.value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " use tags from outer ways\n";
|
|
||||||
}
|
|
||||||
std::set<const osmium::Way*> ways;
|
|
||||||
for (const auto& ring : m_outer_rings) {
|
|
||||||
ring->get_ways(ways);
|
|
||||||
}
|
|
||||||
if (ways.size() == 1) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " only one outer way\n";
|
|
||||||
}
|
|
||||||
osmium::builder::TagListBuilder tl_builder(builder.buffer(), &builder);
|
|
||||||
for (const osmium::Tag& tag : (*ways.begin())->tags()) {
|
|
||||||
tl_builder.add_tag(tag.key(), tag.value());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " multiple outer ways, get common tags\n";
|
|
||||||
}
|
|
||||||
osmium::builder::TagListBuilder tl_builder(builder.buffer(), &builder);
|
|
||||||
add_common_tags(tl_builder, ways);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Go through all the rings and find rings that are not closed.
|
|
||||||
* Problems are reported through the problem reporter.
|
|
||||||
*
|
|
||||||
* @returns true if any rings were not closed, false otherwise
|
|
||||||
*/
|
|
||||||
bool check_for_open_rings() {
|
|
||||||
bool open_rings = false;
|
|
||||||
|
|
||||||
for (const auto& ring : m_rings) {
|
|
||||||
if (!ring.closed()) {
|
|
||||||
open_rings = true;
|
|
||||||
if (m_config.problem_reporter) {
|
|
||||||
m_config.problem_reporter->report_ring_not_closed(ring.get_segment_front().first().location(), ring.get_segment_back().second().location());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return open_rings;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether there are any rings that can be combined with the
|
|
||||||
* given ring to one larger ring by appending the other ring to
|
|
||||||
* the end of this ring.
|
|
||||||
* If the rings can be combined they are and the function returns
|
|
||||||
* true.
|
|
||||||
*/
|
|
||||||
bool possibly_combine_rings_back(ProtoRing& ring) {
|
|
||||||
const osmium::NodeRef& nr = ring.get_segment_back().second();
|
|
||||||
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " possibly_combine_rings_back()\n";
|
|
||||||
}
|
|
||||||
for (auto it = m_rings.begin(); it != m_rings.end(); ++it) {
|
|
||||||
if (&*it != &ring && !it->closed()) {
|
|
||||||
if (has_same_location(nr, it->get_segment_front().first())) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " ring.last=it->first\n";
|
|
||||||
}
|
|
||||||
ring.merge_ring(*it, debug());
|
|
||||||
m_rings.erase(it);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (has_same_location(nr, it->get_segment_back().second())) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " ring.last=it->last\n";
|
|
||||||
}
|
|
||||||
ring.merge_ring_reverse(*it, debug());
|
|
||||||
m_rings.erase(it);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether there are any rings that can be combined with the
|
|
||||||
* given ring to one larger ring by prepending the other ring to
|
|
||||||
* the start of this ring.
|
|
||||||
* If the rings can be combined they are and the function returns
|
|
||||||
* true.
|
|
||||||
*/
|
|
||||||
bool possibly_combine_rings_front(ProtoRing& ring) {
|
|
||||||
const osmium::NodeRef& nr = ring.get_segment_front().first();
|
|
||||||
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " possibly_combine_rings_front()\n";
|
|
||||||
}
|
|
||||||
for (auto it = m_rings.begin(); it != m_rings.end(); ++it) {
|
|
||||||
if (&*it != &ring && !it->closed()) {
|
|
||||||
if (has_same_location(nr, it->get_segment_back().second())) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " ring.first=it->last\n";
|
|
||||||
}
|
|
||||||
ring.swap_segments(*it);
|
|
||||||
ring.merge_ring(*it, debug());
|
|
||||||
m_rings.erase(it);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (has_same_location(nr, it->get_segment_front().first())) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " ring.first=it->first\n";
|
|
||||||
}
|
|
||||||
ring.reverse();
|
|
||||||
ring.merge_ring(*it, debug());
|
|
||||||
m_rings.erase(it);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void split_off_subring(osmium::area::detail::ProtoRing& ring, osmium::area::detail::ProtoRing::segments_type::iterator it, osmium::area::detail::ProtoRing::segments_type::iterator it_begin, osmium::area::detail::ProtoRing::segments_type::iterator it_end) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " subring found at: " << *it << "\n";
|
|
||||||
}
|
|
||||||
ProtoRing new_ring(it_begin, it_end);
|
|
||||||
ring.remove_segments(it_begin, it_end);
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " split into two rings:\n";
|
|
||||||
std::cerr << " " << new_ring << "\n";
|
|
||||||
std::cerr << " " << ring << "\n";
|
|
||||||
}
|
|
||||||
m_rings.push_back(std::move(new_ring));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool has_closed_subring_back(ProtoRing& ring, const NodeRef& nr) {
|
|
||||||
if (ring.segments().size() < 3) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " has_closed_subring_back()\n";
|
|
||||||
}
|
|
||||||
const auto end = ring.segments().end();
|
|
||||||
for (auto it = ring.segments().begin() + 1; it != end - 1; ++it) {
|
|
||||||
if (has_same_location(nr, it->first())) {
|
|
||||||
split_off_subring(ring, it, it, end);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool has_closed_subring_front(ProtoRing& ring, const NodeRef& nr) {
|
|
||||||
if (ring.segments().size() < 3) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " has_closed_subring_front()\n";
|
|
||||||
}
|
|
||||||
const auto end = ring.segments().end();
|
|
||||||
for (auto it = ring.segments().begin() + 1; it != end - 1; ++it) {
|
|
||||||
if (has_same_location(nr, it->second())) {
|
|
||||||
split_off_subring(ring, it, ring.segments().begin(), it+1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool check_for_closed_subring(ProtoRing& ring) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " check_for_closed_subring()\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::area::detail::ProtoRing::segments_type segments(ring.segments().size());
|
|
||||||
std::copy(ring.segments().begin(), ring.segments().end(), segments.begin());
|
|
||||||
std::sort(segments.begin(), segments.end());
|
|
||||||
const auto it = std::adjacent_find(segments.begin(), segments.end(), [this](const osmium::area::detail::NodeRefSegment& s1, const osmium::area::detail::NodeRefSegment& s2) {
|
|
||||||
return has_same_location(s1.first(), s2.first());
|
|
||||||
});
|
|
||||||
if (it == segments.end()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto r1 = std::find_first_of(ring.segments().begin(), ring.segments().end(), it, it+1);
|
|
||||||
assert(r1 != ring.segments().end());
|
|
||||||
const auto r2 = std::find_first_of(ring.segments().begin(), ring.segments().end(), it+1, it+2);
|
|
||||||
assert(r2 != ring.segments().end());
|
|
||||||
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " found subring in ring " << ring << " at " << it->first() << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto m = std::minmax(r1, r2);
|
|
||||||
|
|
||||||
ProtoRing new_ring(m.first, m.second);
|
|
||||||
ring.remove_segments(m.first, m.second);
|
|
||||||
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " split ring1=" << new_ring << "\n";
|
|
||||||
std::cerr << " split ring2=" << ring << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rings.emplace_back(new_ring);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void combine_rings_front(const osmium::area::detail::NodeRefSegment& segment, ProtoRing& ring) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " => match at front of ring\n";
|
|
||||||
}
|
|
||||||
ring.add_segment_front(segment);
|
|
||||||
has_closed_subring_front(ring, segment.first());
|
|
||||||
if (possibly_combine_rings_front(ring)) {
|
|
||||||
check_for_closed_subring(ring);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void combine_rings_back(const osmium::area::detail::NodeRefSegment& segment, ProtoRing& ring) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " => match at back of ring\n";
|
|
||||||
}
|
|
||||||
ring.add_segment_back(segment);
|
|
||||||
has_closed_subring_back(ring, segment.second());
|
|
||||||
if (possibly_combine_rings_back(ring)) {
|
|
||||||
check_for_closed_subring(ring);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append each outer ring together with its inner rings to the
|
|
||||||
* area in the buffer.
|
|
||||||
*/
|
|
||||||
void add_rings_to_area(osmium::builder::AreaBuilder& builder) const {
|
|
||||||
for (const ProtoRing* ring : m_outer_rings) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " ring " << *ring << " is outer\n";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
osmium::builder::OuterRingBuilder ring_builder(builder.buffer(), &builder);
|
|
||||||
ring_builder.add_node_ref(ring->get_segment_front().first());
|
|
||||||
for (const auto& segment : ring->segments()) {
|
|
||||||
ring_builder.add_node_ref(segment.second());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (ProtoRing* inner : ring->inner_rings()) {
|
|
||||||
osmium::builder::InnerRingBuilder ring_builder(builder.buffer(), &builder);
|
|
||||||
ring_builder.add_node_ref(inner->get_segment_front().first());
|
|
||||||
for (const auto& segment : inner->segments()) {
|
|
||||||
ring_builder.add_node_ref(segment.second());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool add_to_existing_ring(osmium::area::detail::NodeRefSegment segment) {
|
|
||||||
int n = 0;
|
|
||||||
for (auto& ring : m_rings) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " check against ring " << n << " " << ring;
|
|
||||||
}
|
|
||||||
if (ring.closed()) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " => ring CLOSED\n";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (has_same_location(ring.get_segment_back().second(), segment.first())) {
|
|
||||||
combine_rings_back(segment, ring);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (has_same_location(ring.get_segment_back().second(), segment.second())) {
|
|
||||||
segment.swap_locations();
|
|
||||||
combine_rings_back(segment, ring);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (has_same_location(ring.get_segment_front().first(), segment.first())) {
|
|
||||||
segment.swap_locations();
|
|
||||||
combine_rings_front(segment, ring);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (has_same_location(ring.get_segment_front().first(), segment.second())) {
|
|
||||||
combine_rings_front(segment, ring);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " => no match\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++n;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_inner_outer(ProtoRing& ring) {
|
|
||||||
const osmium::NodeRef& min_node = ring.min_node();
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " check_inner_outer min_node=" << min_node << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
int above = 0;
|
|
||||||
|
|
||||||
for (auto it = m_segment_list.begin(); it != m_segment_list.end() && it->first().location().x() <= min_node.location().x(); ++it) {
|
|
||||||
if (!ring.contains(*it)) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " segments for count: " << *it;
|
|
||||||
}
|
|
||||||
if (it->to_left_of(min_node.location())) {
|
|
||||||
++count;
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " counted\n";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " not counted\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (it->first().location() == min_node.location()) {
|
|
||||||
if (it->second().location().y() > min_node.location().y()) {
|
|
||||||
++above;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (it->second().location() == min_node.location()) {
|
|
||||||
if (it->first().location().y() > min_node.location().y()) {
|
|
||||||
++above;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " count=" << count << " above=" << above << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
count += above % 2;
|
|
||||||
|
|
||||||
if (count % 2) {
|
|
||||||
ring.set_inner();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_inner_outer_roles() {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " check_inner_outer_roles\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto ringptr : m_outer_rings) {
|
|
||||||
for (const auto& segment : ringptr->segments()) {
|
|
||||||
if (!segment.role_outer()) {
|
|
||||||
++m_inner_outer_mismatches;
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " segment " << segment << " from way " << segment.way()->id() << " should have role 'outer'\n";
|
|
||||||
}
|
|
||||||
if (m_config.problem_reporter) {
|
|
||||||
m_config.problem_reporter->report_role_should_be_outer(segment.way()->id(), segment.first().location(), segment.second().location());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto ringptr : m_inner_rings) {
|
|
||||||
for (const auto& segment : ringptr->segments()) {
|
|
||||||
if (!segment.role_inner()) {
|
|
||||||
++m_inner_outer_mismatches;
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " segment " << segment << " from way " << segment.way()->id() << " should have role 'inner'\n";
|
|
||||||
}
|
|
||||||
if (m_config.problem_reporter) {
|
|
||||||
m_config.problem_reporter->report_role_should_be_inner(segment.way()->id(), segment.first().location(), segment.second().location());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create rings from segments.
|
|
||||||
*/
|
|
||||||
bool create_rings() {
|
|
||||||
m_segment_list.sort();
|
|
||||||
m_segment_list.erase_duplicate_segments();
|
|
||||||
|
|
||||||
// Now we look for segments crossing each other. If there are
|
|
||||||
// any, the multipolygon is invalid.
|
|
||||||
// In the future this could be improved by trying to fix those
|
|
||||||
// cases.
|
|
||||||
if (m_segment_list.find_intersections(m_config.problem_reporter)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now iterator over all segments and add them to rings. Each segment
|
|
||||||
// is tacked on to either end of an existing ring if possible, or a
|
|
||||||
// new ring is started with it.
|
|
||||||
for (const auto& segment : m_segment_list) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " checking segment " << segment << "\n";
|
|
||||||
}
|
|
||||||
if (!add_to_existing_ring(segment)) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " new ring for segment " << segment << "\n";
|
|
||||||
}
|
|
||||||
m_rings.emplace_back(segment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " Rings:\n";
|
|
||||||
for (const auto& ring : m_rings) {
|
|
||||||
std::cerr << " " << ring;
|
|
||||||
if (ring.closed()) {
|
|
||||||
std::cerr << " (closed)";
|
|
||||||
}
|
|
||||||
std::cerr << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check_for_open_rings()) {
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " not all rings are closed\n";
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << " Find inner/outer...\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_rings.size() == 1) {
|
|
||||||
m_outer_rings.push_back(&m_rings.front());
|
|
||||||
} else {
|
|
||||||
for (auto& ring : m_rings) {
|
|
||||||
check_inner_outer(ring);
|
|
||||||
if (ring.outer()) {
|
|
||||||
if (!ring.is_cw()) {
|
|
||||||
ring.reverse();
|
|
||||||
}
|
|
||||||
m_outer_rings.push_back(&ring);
|
|
||||||
} else {
|
|
||||||
if (ring.is_cw()) {
|
|
||||||
ring.reverse();
|
|
||||||
}
|
|
||||||
m_inner_rings.push_back(&ring);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_outer_rings.size() == 1) {
|
|
||||||
for (auto inner : m_inner_rings) {
|
|
||||||
m_outer_rings.front()->add_inner_ring(inner);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// sort outer rings by size, smallest first
|
|
||||||
std::sort(m_outer_rings.begin(), m_outer_rings.end(), [](ProtoRing* a, ProtoRing* b) {
|
|
||||||
return a->area() < b->area();
|
|
||||||
});
|
|
||||||
for (auto inner : m_inner_rings) {
|
|
||||||
for (auto outer : m_outer_rings) {
|
|
||||||
if (inner->is_in(outer)) {
|
|
||||||
outer->add_inner_ring(inner);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
check_inner_outer_roles();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef osmium::area::AssemblerConfig config_type;
|
|
||||||
|
|
||||||
explicit Assembler(const config_type& config) :
|
|
||||||
m_config(config),
|
|
||||||
m_segment_list(config.debug) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~Assembler() = default;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assemble an area from the given way.
|
|
||||||
* The resulting area is put into the out_buffer.
|
|
||||||
*/
|
|
||||||
void operator()(const osmium::Way& way, osmium::memory::Buffer& out_buffer) {
|
|
||||||
if (m_config.problem_reporter) {
|
|
||||||
m_config.problem_reporter->set_object(osmium::item_type::way, way.id());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!way.ends_have_same_id()) {
|
|
||||||
if (m_config.problem_reporter) {
|
|
||||||
m_config.problem_reporter->report_duplicate_node(way.nodes().front().ref(), way.nodes().back().ref(), way.nodes().front().location());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_segment_list.extract_segments_from_way(way, "outer");
|
|
||||||
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << "\nBuild way id()=" << way.id() << " segments.size()=" << m_segment_list.size() << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now create the Area object and add the attributes and tags
|
|
||||||
// from the relation.
|
|
||||||
{
|
|
||||||
osmium::builder::AreaBuilder builder(out_buffer);
|
|
||||||
builder.initialize_from_object(way);
|
|
||||||
|
|
||||||
if (create_rings()) {
|
|
||||||
add_tags_to_area(builder, way);
|
|
||||||
add_rings_to_area(builder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out_buffer.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assemble an area from the given relation and its members.
|
|
||||||
* All members are to be found in the in_buffer at the offsets
|
|
||||||
* given by the members parameter.
|
|
||||||
* The resulting area is put into the out_buffer.
|
|
||||||
*/
|
|
||||||
void operator()(const osmium::Relation& relation, const std::vector<size_t>& members, const osmium::memory::Buffer& in_buffer, osmium::memory::Buffer& out_buffer) {
|
|
||||||
if (m_config.problem_reporter) {
|
|
||||||
m_config.problem_reporter->set_object(osmium::item_type::relation, relation.id());
|
|
||||||
}
|
|
||||||
|
|
||||||
m_segment_list.extract_segments_from_ways(relation, members, in_buffer);
|
|
||||||
|
|
||||||
if (debug()) {
|
|
||||||
std::cerr << "\nBuild relation id()=" << relation.id() << " members.size()=" << members.size() << " segments.size()=" << m_segment_list.size() << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t area_offset = out_buffer.committed();
|
|
||||||
|
|
||||||
// Now create the Area object and add the attributes and tags
|
|
||||||
// from the relation.
|
|
||||||
{
|
|
||||||
osmium::builder::AreaBuilder builder(out_buffer);
|
|
||||||
builder.initialize_from_object(relation);
|
|
||||||
|
|
||||||
if (create_rings()) {
|
|
||||||
add_tags_to_area(builder, relation);
|
|
||||||
add_rings_to_area(builder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out_buffer.commit();
|
|
||||||
|
|
||||||
const osmium::TagList& area_tags = out_buffer.get<osmium::Area>(area_offset).tags(); // tags of the area we just built
|
|
||||||
|
|
||||||
// Find all closed ways that are inner rings and check their
|
|
||||||
// tags. If they are not the same as the tags of the area we
|
|
||||||
// just built, add them to a list and later build areas for
|
|
||||||
// them, too.
|
|
||||||
std::vector<const osmium::Way*> ways_that_should_be_areas;
|
|
||||||
if (m_inner_outer_mismatches == 0) {
|
|
||||||
auto memit = relation.members().begin();
|
|
||||||
for (size_t offset : members) {
|
|
||||||
if (!std::strcmp(memit->role(), "inner")) {
|
|
||||||
const osmium::Way& way = in_buffer.get<const osmium::Way>(offset);
|
|
||||||
if (!way.nodes().empty() && way.is_closed() && way.tags().size() > 0) {
|
|
||||||
auto d = std::count_if(way.tags().begin(), way.tags().end(), filter());
|
|
||||||
if (d > 0) {
|
|
||||||
osmium::tags::KeyFilter::iterator way_fi_begin(filter(), way.tags().begin(), way.tags().end());
|
|
||||||
osmium::tags::KeyFilter::iterator way_fi_end(filter(), way.tags().end(), way.tags().end());
|
|
||||||
osmium::tags::KeyFilter::iterator area_fi_begin(filter(), area_tags.begin(), area_tags.end());
|
|
||||||
osmium::tags::KeyFilter::iterator area_fi_end(filter(), area_tags.end(), area_tags.end());
|
|
||||||
|
|
||||||
if (!std::equal(way_fi_begin, way_fi_end, area_fi_begin) || d != std::distance(area_fi_begin, area_fi_end)) {
|
|
||||||
ways_that_should_be_areas.push_back(&way);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++memit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now build areas for all ways found in the last step.
|
|
||||||
for (const osmium::Way* way : ways_that_should_be_areas) {
|
|
||||||
Assembler assembler(m_config);
|
|
||||||
assembler(*way, out_buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class Assembler
|
|
||||||
|
|
||||||
} // namespace area
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_AREA_ASSEMBLER_HPP
|
|
@ -1,274 +0,0 @@
|
|||||||
#ifndef OSMIUM_AREA_DETAIL_NODE_REF_SEGMENT_HPP
|
|
||||||
#define OSMIUM_AREA_DETAIL_NODE_REF_SEGMENT_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstring>
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/node_ref.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
class Way;
|
|
||||||
|
|
||||||
namespace area {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Namespace for Osmium internal use
|
|
||||||
*/
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This helper class for the Assembler class models a segment.
|
|
||||||
* Segments are the connection between
|
|
||||||
* two nodes and they all have their smaller coordinate at the
|
|
||||||
* beginning of the segment. Smaller, in this case, means smaller x
|
|
||||||
* coordinate, and if they are the same smaller y coordinate.
|
|
||||||
*/
|
|
||||||
class NodeRefSegment {
|
|
||||||
|
|
||||||
osmium::NodeRef m_first;
|
|
||||||
osmium::NodeRef m_second;
|
|
||||||
|
|
||||||
/// Role of the member this segment was from.
|
|
||||||
const char* m_role;
|
|
||||||
|
|
||||||
/// Way this segment was from.
|
|
||||||
const osmium::Way* m_way;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void swap_locations() {
|
|
||||||
using std::swap;
|
|
||||||
swap(m_first, m_second);
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit NodeRefSegment() noexcept :
|
|
||||||
m_first(),
|
|
||||||
m_second(),
|
|
||||||
m_role(nullptr),
|
|
||||||
m_way(nullptr) {
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit NodeRefSegment(const osmium::NodeRef& nr1, const osmium::NodeRef& nr2, const char* role, const osmium::Way* way) :
|
|
||||||
m_first(nr1),
|
|
||||||
m_second(nr2),
|
|
||||||
m_role(role),
|
|
||||||
m_way(way) {
|
|
||||||
if (nr2.location() < nr1.location()) {
|
|
||||||
swap_locations();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeRefSegment(const NodeRefSegment&) = default;
|
|
||||||
NodeRefSegment(NodeRefSegment&&) = default;
|
|
||||||
|
|
||||||
NodeRefSegment& operator=(const NodeRefSegment&) = default;
|
|
||||||
NodeRefSegment& operator=(NodeRefSegment&&) = default;
|
|
||||||
|
|
||||||
~NodeRefSegment() = default;
|
|
||||||
|
|
||||||
/// Return first NodeRef of Segment according to sorting order (bottom left to top right).
|
|
||||||
const osmium::NodeRef& first() const noexcept {
|
|
||||||
return m_first;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return second NodeRef of Segment according to sorting order (bottom left to top right).
|
|
||||||
const osmium::NodeRef& second() const noexcept {
|
|
||||||
return m_second;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool to_left_of(const osmium::Location& location) const {
|
|
||||||
// std::cerr << "segment " << first() << "--" << second() << " to_left_of(" << location << "\n";
|
|
||||||
|
|
||||||
if (first().location() == location || second().location() == location) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::pair<osmium::Location, osmium::Location> mm = std::minmax(first().location(), second().location(), [](const osmium::Location a, const osmium::Location b) {
|
|
||||||
return a.y() < b.y();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (mm.first.y() >= location.y() || mm.second.y() < location.y() || first().location().x() > location.x()) {
|
|
||||||
// std::cerr << " false\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t ax = mm.first.x();
|
|
||||||
int64_t bx = mm.second.x();
|
|
||||||
int64_t lx = location.x();
|
|
||||||
int64_t ay = mm.first.y();
|
|
||||||
int64_t by = mm.second.y();
|
|
||||||
int64_t ly = location.y();
|
|
||||||
return ((bx - ax)*(ly - ay) - (by - ay)*(lx - ax)) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool role_outer() const noexcept {
|
|
||||||
return !strcmp(m_role, "outer");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool role_inner() const noexcept {
|
|
||||||
return !strcmp(m_role, "inner");
|
|
||||||
}
|
|
||||||
|
|
||||||
const osmium::Way* way() const noexcept {
|
|
||||||
return m_way;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class NodeRefSegment
|
|
||||||
|
|
||||||
/// NodeRefSegments are equal if both their locations are equal
|
|
||||||
inline bool operator==(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept {
|
|
||||||
return lhs.first().location() == rhs.first().location() && lhs.second().location() == rhs.second().location();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept {
|
|
||||||
return ! (lhs == rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NodeRefSegments are "smaller" if they are to the left and down of another
|
|
||||||
* segment. The first() location is checked first() and only if they have the
|
|
||||||
* same first() location the second() location is taken into account.
|
|
||||||
*/
|
|
||||||
inline bool operator<(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept {
|
|
||||||
return (lhs.first().location() == rhs.first().location() && lhs.second().location() < rhs.second().location()) || lhs.first().location() < rhs.first().location();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept {
|
|
||||||
return rhs < lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept {
|
|
||||||
return ! (rhs < lhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator>=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept {
|
|
||||||
return ! (lhs < rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TChar, typename TTraits>
|
|
||||||
inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const NodeRefSegment& segment) {
|
|
||||||
return out << segment.first() << "--" << segment.second();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool outside_x_range(const NodeRefSegment& s1, const NodeRefSegment& s2) noexcept {
|
|
||||||
if (s1.first().location().x() > s2.second().location().x()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool y_range_overlap(const NodeRefSegment& s1, const NodeRefSegment& s2) {
|
|
||||||
const std::pair<int32_t, int32_t> m1 = std::minmax(s1.first().location().y(), s1.second().location().y());
|
|
||||||
const std::pair<int32_t, int32_t> m2 = std::minmax(s2.first().location().y(), s2.second().location().y());
|
|
||||||
if (m1.first > m2.second || m2.first > m1.second) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the intersection between two NodeRefSegments. The
|
|
||||||
* result is returned as a Location. Note that because the Location
|
|
||||||
* uses integers with limited precision internally, the result
|
|
||||||
* might be slightly different than the numerically correct
|
|
||||||
* location.
|
|
||||||
*
|
|
||||||
* This function uses integer arithmentic as much as possible and
|
|
||||||
* will not work if the segments are longer than about half the
|
|
||||||
* planet. This shouldn't happen with real data, so it isn't a big
|
|
||||||
* problem.
|
|
||||||
*
|
|
||||||
* If the segments touch in one of their endpoints, it doesn't
|
|
||||||
* count as an intersection.
|
|
||||||
*
|
|
||||||
* If the segments intersect not in a single point but in multiple
|
|
||||||
* points, ie if they overlap, this is NOT detected.
|
|
||||||
*
|
|
||||||
* @returns Undefined osmium::Location if there is no intersection
|
|
||||||
* or a defined Location if the segments intersect.
|
|
||||||
*/
|
|
||||||
inline osmium::Location calculate_intersection(const NodeRefSegment& s1, const NodeRefSegment& s2) {
|
|
||||||
if (s1.first().location() == s2.first().location() ||
|
|
||||||
s1.first().location() == s2.second().location() ||
|
|
||||||
s1.second().location() == s2.first().location() ||
|
|
||||||
s1.second().location() == s2.second().location()) {
|
|
||||||
return osmium::Location();
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t s1ax = s1.first().x();
|
|
||||||
int64_t s1ay = s1.first().y();
|
|
||||||
int64_t s1bx = s1.second().x();
|
|
||||||
int64_t s1by = s1.second().y();
|
|
||||||
int64_t s2ax = s2.first().x();
|
|
||||||
int64_t s2ay = s2.first().y();
|
|
||||||
int64_t s2bx = s2.second().x();
|
|
||||||
int64_t s2by = s2.second().y();
|
|
||||||
|
|
||||||
int64_t d = (s2by - s2ay) * (s1bx - s1ax) -
|
|
||||||
(s2bx - s2ax) * (s1by - s1ay);
|
|
||||||
|
|
||||||
if (d != 0) {
|
|
||||||
int64_t na = (s2bx - s2ax) * (s1ay - s2ay) -
|
|
||||||
(s2by - s2ay) * (s1ax - s2ax);
|
|
||||||
|
|
||||||
int64_t nb = (s1bx - s1ax) * (s1ay - s2ay) -
|
|
||||||
(s1by - s1ay) * (s1ax - s2ax);
|
|
||||||
|
|
||||||
if ((d > 0 && na >= 0 && na <= d && nb >= 0 && nb <= d) ||
|
|
||||||
(d < 0 && na <= 0 && na >= d && nb <= 0 && nb >= d)) {
|
|
||||||
|
|
||||||
double ua = double(na) / d;
|
|
||||||
int32_t ix = int32_t(s1ax + ua*(s1bx - s1ax));
|
|
||||||
int32_t iy = int32_t(s1ay + ua*(s1by - s1ay));
|
|
||||||
|
|
||||||
return osmium::Location(ix, iy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return osmium::Location();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
} // namespace area
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_AREA_DETAIL_NODE_REF_SEGMENT_HPP
|
|
@ -1,277 +0,0 @@
|
|||||||
#ifndef OSMIUM_AREA_DETAIL_PROTO_RING_HPP
|
|
||||||
#define OSMIUM_AREA_DETAIL_PROTO_RING_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <iostream>
|
|
||||||
#include <iterator>
|
|
||||||
#include <set>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/node_ref.hpp>
|
|
||||||
#include <osmium/area/detail/node_ref_segment.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace area {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A ring in the process of being built by the Assembler object.
|
|
||||||
*/
|
|
||||||
class ProtoRing {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef std::vector<NodeRefSegment> segments_type;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// segments in this ring
|
|
||||||
segments_type m_segments;
|
|
||||||
|
|
||||||
bool m_outer {true};
|
|
||||||
|
|
||||||
// if this is an outer ring, these point to it's inner rings (if any)
|
|
||||||
std::vector<ProtoRing*> m_inner;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit ProtoRing(const NodeRefSegment& segment) noexcept :
|
|
||||||
m_segments() {
|
|
||||||
add_segment_back(segment);
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit ProtoRing(segments_type::const_iterator sbegin, segments_type::const_iterator send) :
|
|
||||||
m_segments(static_cast<size_t>(std::distance(sbegin, send))) {
|
|
||||||
std::copy(sbegin, send, m_segments.begin());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool outer() const noexcept {
|
|
||||||
return m_outer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_inner() noexcept {
|
|
||||||
m_outer = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
segments_type& segments() noexcept {
|
|
||||||
return m_segments;
|
|
||||||
}
|
|
||||||
|
|
||||||
const segments_type& segments() const noexcept {
|
|
||||||
return m_segments;
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove_segments(segments_type::iterator sbegin, segments_type::iterator send) {
|
|
||||||
m_segments.erase(sbegin, send);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_segment_front(const NodeRefSegment& segment) {
|
|
||||||
m_segments.insert(m_segments.begin(), segment);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_segment_back(const NodeRefSegment& segment) {
|
|
||||||
m_segments.push_back(segment);
|
|
||||||
}
|
|
||||||
|
|
||||||
const NodeRefSegment& get_segment_front() const {
|
|
||||||
return m_segments.front();
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeRefSegment& get_segment_front() {
|
|
||||||
return m_segments.front();
|
|
||||||
}
|
|
||||||
|
|
||||||
const NodeRefSegment& get_segment_back() const {
|
|
||||||
return m_segments.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeRefSegment& get_segment_back() {
|
|
||||||
return m_segments.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool closed() const {
|
|
||||||
return m_segments.front().first().location() == m_segments.back().second().location();
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t sum() const {
|
|
||||||
int64_t sum = 0;
|
|
||||||
|
|
||||||
for (const auto& segment : m_segments) {
|
|
||||||
sum += static_cast<int64_t>(segment.first().location().x()) * static_cast<int64_t>(segment.second().location().y()) -
|
|
||||||
static_cast<int64_t>(segment.second().location().x()) * static_cast<int64_t>(segment.first().location().y());
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_cw() const {
|
|
||||||
return sum() <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t area() const {
|
|
||||||
return std::abs(sum()) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap_segments(ProtoRing& other) {
|
|
||||||
using std::swap;
|
|
||||||
swap(m_segments, other.m_segments);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_inner_ring(ProtoRing* ring) {
|
|
||||||
m_inner.push_back(ring);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<ProtoRing*>& inner_rings() const {
|
|
||||||
return m_inner;
|
|
||||||
}
|
|
||||||
|
|
||||||
void print(std::ostream& out) const {
|
|
||||||
out << "[";
|
|
||||||
bool first = true;
|
|
||||||
for (const auto& segment : m_segments) {
|
|
||||||
if (first) {
|
|
||||||
out << segment.first().ref();
|
|
||||||
}
|
|
||||||
out << ',' << segment.second().ref();
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
out << "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
void reverse() {
|
|
||||||
std::for_each(m_segments.begin(), m_segments.end(), [](NodeRefSegment& segment) {
|
|
||||||
segment.swap_locations();
|
|
||||||
});
|
|
||||||
std::reverse(m_segments.begin(), m_segments.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merge other ring to end of this ring.
|
|
||||||
*/
|
|
||||||
void merge_ring(const ProtoRing& other, bool debug) {
|
|
||||||
if (debug) {
|
|
||||||
std::cerr << " MERGE rings ";
|
|
||||||
print(std::cerr);
|
|
||||||
std::cerr << " to ";
|
|
||||||
other.print(std::cerr);
|
|
||||||
std::cerr << "\n";
|
|
||||||
}
|
|
||||||
m_segments.insert(m_segments.end(), other.m_segments.begin(), other.m_segments.end());
|
|
||||||
if (debug) {
|
|
||||||
std::cerr << " result ring: ";
|
|
||||||
print(std::cerr);
|
|
||||||
std::cerr << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void merge_ring_reverse(const ProtoRing& other, bool debug) {
|
|
||||||
if (debug) {
|
|
||||||
std::cerr << " MERGE rings (reverse) ";
|
|
||||||
print(std::cerr);
|
|
||||||
std::cerr << " to ";
|
|
||||||
other.print(std::cerr);
|
|
||||||
std::cerr << "\n";
|
|
||||||
}
|
|
||||||
size_t n = m_segments.size();
|
|
||||||
m_segments.resize(n + other.m_segments.size());
|
|
||||||
std::transform(other.m_segments.rbegin(), other.m_segments.rend(), m_segments.begin() + static_cast<segments_type::difference_type>(n), [](NodeRefSegment segment) {
|
|
||||||
segment.swap_locations();
|
|
||||||
return segment;
|
|
||||||
});
|
|
||||||
if (debug) {
|
|
||||||
std::cerr << " result ring: ";
|
|
||||||
print(std::cerr);
|
|
||||||
std::cerr << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const NodeRef& min_node() const {
|
|
||||||
auto it = std::min_element(m_segments.begin(), m_segments.end());
|
|
||||||
if (location_less()(it->first(), it->second())) {
|
|
||||||
return it->first();
|
|
||||||
} else {
|
|
||||||
return it->second();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_in(ProtoRing* outer) {
|
|
||||||
osmium::Location testpoint = segments().front().first().location();
|
|
||||||
bool is_in = false;
|
|
||||||
|
|
||||||
for (size_t i = 0, j = outer->segments().size()-1; i < outer->segments().size(); j = i++) {
|
|
||||||
if (((outer->segments()[i].first().location().y() > testpoint.y()) != (outer->segments()[j].first().location().y() > testpoint.y())) &&
|
|
||||||
(testpoint.x() < (outer->segments()[j].first().location().x() - outer->segments()[i].first().location().x()) * (testpoint.y() - outer->segments()[i].first().location().y()) / (outer->segments()[j].first().location().y() - outer->segments()[i].first().location().y()) + outer->segments()[i].first().location().x()) ) {
|
|
||||||
is_in = !is_in;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return is_in;
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_ways(std::set<const osmium::Way*>& ways) {
|
|
||||||
for (const auto& segment : m_segments) {
|
|
||||||
ways.insert(segment.way());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool contains(const NodeRefSegment& segment) const {
|
|
||||||
for (const auto& s : m_segments) {
|
|
||||||
if (s == segment || (s.first() == segment.second() && s.second() == segment.first())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class ProtoRing
|
|
||||||
|
|
||||||
template <typename TChar, typename TTraits>
|
|
||||||
inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const ProtoRing& ring) {
|
|
||||||
ring.print(out);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
} // namespace area
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_AREA_DETAIL_PROTO_RING_HPP
|
|
@ -1,218 +0,0 @@
|
|||||||
#ifndef OSMIUM_AREA_DETAIL_SEGMENT_LIST_HPP
|
|
||||||
#define OSMIUM_AREA_DETAIL_SEGMENT_LIST_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <osmium/area/problem_reporter.hpp>
|
|
||||||
#include <osmium/area/detail/node_ref_segment.hpp>
|
|
||||||
#include <osmium/memory/buffer.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/node_ref.hpp>
|
|
||||||
#include <osmium/osm/relation.hpp>
|
|
||||||
#include <osmium/osm/way.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace area {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a helper class for the area assembler. It models
|
|
||||||
* a list of segments.
|
|
||||||
*/
|
|
||||||
class SegmentList {
|
|
||||||
|
|
||||||
typedef std::vector<NodeRefSegment> slist_type;
|
|
||||||
|
|
||||||
slist_type m_segments;
|
|
||||||
|
|
||||||
bool m_debug;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit SegmentList(bool debug) noexcept :
|
|
||||||
m_debug(debug) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~SegmentList() = default;
|
|
||||||
|
|
||||||
SegmentList(const SegmentList&) = delete;
|
|
||||||
SegmentList(SegmentList&&) = delete;
|
|
||||||
|
|
||||||
SegmentList& operator=(const SegmentList&) = delete;
|
|
||||||
SegmentList& operator=(SegmentList&&) = delete;
|
|
||||||
|
|
||||||
/// The number of segments in the list.
|
|
||||||
size_t size() const noexcept {
|
|
||||||
return m_segments.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const noexcept {
|
|
||||||
return m_segments.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef slist_type::const_iterator const_iterator;
|
|
||||||
|
|
||||||
const_iterator begin() const noexcept {
|
|
||||||
return m_segments.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end() const noexcept {
|
|
||||||
return m_segments.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable or disable debug output to stderr. This is for Osmium
|
|
||||||
* developers only.
|
|
||||||
*/
|
|
||||||
void enable_debug_output(bool debug = true) noexcept {
|
|
||||||
m_debug = debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clear the list of segments. All segments are removed.
|
|
||||||
void clear() {
|
|
||||||
m_segments.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sort the list of segments.
|
|
||||||
void sort() {
|
|
||||||
std::sort(m_segments.begin(), m_segments.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract segments from given way and add them to the list.
|
|
||||||
*
|
|
||||||
* Segments connecting two nodes with the same location (ie same
|
|
||||||
* node or different node with same location) are removed.
|
|
||||||
*
|
|
||||||
* XXX should two nodes with same location be reported?
|
|
||||||
*/
|
|
||||||
void extract_segments_from_way(const osmium::Way& way, const char* role) {
|
|
||||||
osmium::NodeRef last_nr;
|
|
||||||
for (const osmium::NodeRef& nr : way.nodes()) {
|
|
||||||
if (last_nr.location() && last_nr.location() != nr.location()) {
|
|
||||||
m_segments.emplace_back(last_nr, nr, role, &way);
|
|
||||||
}
|
|
||||||
last_nr = nr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract all segments from all ways that make up this
|
|
||||||
* multipolygon relation and add them to the list.
|
|
||||||
*/
|
|
||||||
void extract_segments_from_ways(const osmium::Relation& relation, const std::vector<size_t>& members, const osmium::memory::Buffer& in_buffer) {
|
|
||||||
auto member_it = relation.members().begin();
|
|
||||||
for (size_t offset : members) {
|
|
||||||
const osmium::Way& way = in_buffer.get<const osmium::Way>(offset);
|
|
||||||
extract_segments_from_way(way, member_it->role());
|
|
||||||
++member_it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find duplicate segments (ie same start and end point) in the
|
|
||||||
* list and remove them. This will always remove pairs of the same
|
|
||||||
* segment. So if there are three, for instance, two will be
|
|
||||||
* removed and one will be left.
|
|
||||||
*/
|
|
||||||
void erase_duplicate_segments() {
|
|
||||||
while (true) {
|
|
||||||
auto it = std::adjacent_find(m_segments.begin(), m_segments.end());
|
|
||||||
if (it == m_segments.end()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_debug) {
|
|
||||||
std::cerr << " erase duplicate segment: " << *it << "\n";
|
|
||||||
}
|
|
||||||
m_segments.erase(it, it+2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find intersection between segments.
|
|
||||||
*
|
|
||||||
* @param problem_reporter Any intersections found are reported to this object.
|
|
||||||
* @returns true if there are intersections.
|
|
||||||
*/
|
|
||||||
bool find_intersections(osmium::area::ProblemReporter* problem_reporter) const {
|
|
||||||
if (m_segments.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool found_intersections = false;
|
|
||||||
|
|
||||||
for (auto it1 = m_segments.begin(); it1 != m_segments.end()-1; ++it1) {
|
|
||||||
const NodeRefSegment& s1 = *it1;
|
|
||||||
for (auto it2 = it1+1; it2 != m_segments.end(); ++it2) {
|
|
||||||
const NodeRefSegment& s2 = *it2;
|
|
||||||
|
|
||||||
assert(s1 != s2); // erase_duplicate_segments() should have made sure of that
|
|
||||||
|
|
||||||
if (outside_x_range(s2, s1)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y_range_overlap(s1, s2)) {
|
|
||||||
osmium::Location intersection = calculate_intersection(s1, s2);
|
|
||||||
if (intersection) {
|
|
||||||
found_intersections = true;
|
|
||||||
if (m_debug) {
|
|
||||||
std::cerr << " segments " << s1 << " and " << s2 << " intersecting at " << intersection << "\n";
|
|
||||||
}
|
|
||||||
if (problem_reporter) {
|
|
||||||
problem_reporter->report_intersection(s1.way()->id(), s1.first().location(), s1.second().location(), s2.way()->id(), s2.first().location(), s2.second().location(), intersection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found_intersections;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class SegmentList
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
} // namespace area
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_AREA_DETAIL_SEGMENT_LIST_HPP
|
|
@ -1,201 +0,0 @@
|
|||||||
#ifndef OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP
|
|
||||||
#define OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstring>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <osmium/memory/buffer.hpp>
|
|
||||||
#include <osmium/osm/item_type.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/node_ref.hpp>
|
|
||||||
#include <osmium/osm/relation.hpp>
|
|
||||||
#include <osmium/osm/tag.hpp>
|
|
||||||
#include <osmium/osm/way.hpp>
|
|
||||||
#include <osmium/relations/collector.hpp>
|
|
||||||
#include <osmium/relations/detail/member_meta.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace relations {
|
|
||||||
class RelationMeta;
|
|
||||||
} // namespace relations
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Code related to the building of areas (multipolygons) from relations.
|
|
||||||
*/
|
|
||||||
namespace area {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* The actual assembling of the areas is done by the assembler
|
|
||||||
* class given as template argument.
|
|
||||||
*
|
|
||||||
* @tparam TAssembler Multipolygon Assembler class.
|
|
||||||
*/
|
|
||||||
template <typename TAssembler>
|
|
||||||
class MultipolygonCollector : public osmium::relations::Collector<MultipolygonCollector<TAssembler>, false, true, false> {
|
|
||||||
|
|
||||||
typedef typename osmium::relations::Collector<MultipolygonCollector<TAssembler>, false, true, false> collector_type;
|
|
||||||
|
|
||||||
typedef typename TAssembler::config_type assembler_config_type;
|
|
||||||
const assembler_config_type m_assembler_config;
|
|
||||||
|
|
||||||
osmium::memory::Buffer m_output_buffer;
|
|
||||||
|
|
||||||
static constexpr size_t initial_output_buffer_size = 1024 * 1024;
|
|
||||||
static constexpr size_t max_buffer_size_for_flush = 100 * 1024;
|
|
||||||
|
|
||||||
void flush_output_buffer() {
|
|
||||||
if (this->callback()) {
|
|
||||||
osmium::memory::Buffer buffer(initial_output_buffer_size);
|
|
||||||
using std::swap;
|
|
||||||
swap(buffer, m_output_buffer);
|
|
||||||
this->callback()(std::move(buffer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void possibly_flush_output_buffer() {
|
|
||||||
if (m_output_buffer.committed() > max_buffer_size_for_flush) {
|
|
||||||
flush_output_buffer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit MultipolygonCollector(const assembler_config_type& assembler_config) :
|
|
||||||
collector_type(),
|
|
||||||
m_assembler_config(assembler_config),
|
|
||||||
m_output_buffer(initial_output_buffer_size, osmium::memory::Buffer::auto_grow::yes) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We are interested in all relations tagged with type=multipolygon
|
|
||||||
* or type=boundary.
|
|
||||||
*
|
|
||||||
* Overwritten from the base class.
|
|
||||||
*/
|
|
||||||
bool keep_relation(const osmium::Relation& relation) const {
|
|
||||||
const char* type = relation.tags().get_value_by_key("type");
|
|
||||||
|
|
||||||
// ignore relations without "type" tag
|
|
||||||
if (!type) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!strcmp(type, "multipolygon")) || (!strcmp(type, "boundary"))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overwritten from the base class.
|
|
||||||
*/
|
|
||||||
bool keep_member(const osmium::relations::RelationMeta& /*relation_meta*/, const osmium::RelationMember& member) const {
|
|
||||||
// We are only interested in members of type way.
|
|
||||||
return member.type() == osmium::item_type::way;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is called when a way is not in any multipolygon
|
|
||||||
* relation.
|
|
||||||
*
|
|
||||||
* Overwritten from the base class.
|
|
||||||
*/
|
|
||||||
void way_not_in_any_relation(const osmium::Way& way) {
|
|
||||||
// you need at least 4 nodes to make up a polygon
|
|
||||||
if (way.nodes().size() <= 3) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (!way.nodes().front().location() || !way.nodes().back().location()) {
|
|
||||||
throw osmium::invalid_location("invalid location");
|
|
||||||
}
|
|
||||||
if (way.ends_have_same_location()) {
|
|
||||||
// way is closed and has enough nodes, build simple multipolygon
|
|
||||||
TAssembler assembler(m_assembler_config);
|
|
||||||
assembler(way, m_output_buffer);
|
|
||||||
possibly_flush_output_buffer();
|
|
||||||
}
|
|
||||||
} catch (osmium::invalid_location&) {
|
|
||||||
// XXX ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void complete_relation(osmium::relations::RelationMeta& relation_meta) {
|
|
||||||
const osmium::Relation& relation = this->get_relation(relation_meta);
|
|
||||||
std::vector<size_t> offsets;
|
|
||||||
for (const auto& member : relation.members()) {
|
|
||||||
if (member.ref() != 0) {
|
|
||||||
offsets.push_back(this->get_offset(member.type(), member.ref()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
TAssembler assembler(m_assembler_config);
|
|
||||||
assembler(relation, offsets, this->members_buffer(), m_output_buffer);
|
|
||||||
possibly_flush_output_buffer();
|
|
||||||
} catch (osmium::invalid_location&) {
|
|
||||||
// XXX ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush() {
|
|
||||||
flush_output_buffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::memory::Buffer read() {
|
|
||||||
osmium::memory::Buffer buffer(initial_output_buffer_size, osmium::memory::Buffer::auto_grow::yes);
|
|
||||||
|
|
||||||
using std::swap;
|
|
||||||
swap(buffer, m_output_buffer);
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class MultipolygonCollector
|
|
||||||
|
|
||||||
} // namespace area
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_AREA_MULTIPOLYGON_COLLECTOR_HPP
|
|
@ -1,149 +0,0 @@
|
|||||||
#ifndef OSMIUM_AREA_PROBLEM_REPORTER_HPP
|
|
||||||
#define OSMIUM_AREA_PROBLEM_REPORTER_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <osmium/osm/item_type.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/types.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace area {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When assembling a multipolygon/area from a multipolygon relation
|
|
||||||
* or a closed way several problems can be detected. This includes
|
|
||||||
* intersections between lines, wrong role attributes on relation
|
|
||||||
* members etc. These problems are reported by the area::Assembler
|
|
||||||
* class to the ProblemReporter class or one of its child classes.
|
|
||||||
*
|
|
||||||
* This is the parent class which does nothing with the reports.
|
|
||||||
* Child classes are expected to implement different ways of
|
|
||||||
* reporting the problems.
|
|
||||||
*/
|
|
||||||
class ProblemReporter {
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// Type of object we are currently working on
|
|
||||||
osmium::item_type m_object_type;
|
|
||||||
|
|
||||||
// ID of the relation/way we are currently working on
|
|
||||||
osmium::object_id_type m_object_id;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
ProblemReporter() = default;
|
|
||||||
|
|
||||||
virtual ~ProblemReporter() = default;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the object the next problem reports will be on.
|
|
||||||
*
|
|
||||||
* @param object_type The type of the object.
|
|
||||||
* @param object_id The ID of the object.
|
|
||||||
*/
|
|
||||||
void set_object(osmium::item_type object_type, osmium::object_id_type object_id) noexcept {
|
|
||||||
m_object_type = object_type;
|
|
||||||
m_object_id = object_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable "unused-parameter" warning, so that the compiler will not complain.
|
|
||||||
// We can't remove the parameter names, because then doxygen will complain.
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report a duplicate node, ie. two nodes with the same location.
|
|
||||||
*
|
|
||||||
* @param node_id1 ID of the first node.
|
|
||||||
* @param node_id2 ID of the second node.
|
|
||||||
* @param location Location of both nodes.
|
|
||||||
*/
|
|
||||||
virtual void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report an intersection between two segments.
|
|
||||||
*
|
|
||||||
* @param way1_id ID of the first involved way.
|
|
||||||
* @param way1_seg_start Location where the segment of the first way with the intersection starts
|
|
||||||
* @param way1_seg_end Location where the segment of the first way with the intersection ends
|
|
||||||
* @param way2_id ID of the second involved way.
|
|
||||||
* @param way2_seg_start Location where the segment of the second way with the intersection starts
|
|
||||||
* @param way2_seg_end Location where the segment of the second way with the intersection ends
|
|
||||||
* @param intersection Location of the intersection. This might be slightly off the correct location due to rounding.
|
|
||||||
*/
|
|
||||||
virtual void report_intersection(osmium::object_id_type way1_id, osmium::Location way1_seg_start, osmium::Location way1_seg_end,
|
|
||||||
osmium::object_id_type way2_id, osmium::Location way2_seg_start, osmium::Location way2_seg_end, osmium::Location intersection) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report an open ring.
|
|
||||||
*
|
|
||||||
* @param end1 Location of the first open end.
|
|
||||||
* @param end2 Location of the second open end.
|
|
||||||
*/
|
|
||||||
virtual void report_ring_not_closed(osmium::Location end1, osmium::Location end2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report a segment that should have role "outer", but has a different role.
|
|
||||||
*
|
|
||||||
* @param way_id ID of the way this segment is in.
|
|
||||||
* @param seg_start Start of the segment with the wrong role.
|
|
||||||
* @param seg_end End of the segment with the wrong role.
|
|
||||||
*/
|
|
||||||
virtual void report_role_should_be_outer(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report a segment that should have role "inner", but has a different role.
|
|
||||||
*
|
|
||||||
* @param way_id ID of the way this segment is in.
|
|
||||||
* @param seg_start Start of the segment with the wrong role.
|
|
||||||
* @param seg_end End of the segment with the wrong role.
|
|
||||||
*/
|
|
||||||
virtual void report_role_should_be_inner(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
}; // class ProblemReporter
|
|
||||||
|
|
||||||
} // namespace area
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_AREA_PROBLEM_REPORTER_HPP
|
|
@ -1,96 +0,0 @@
|
|||||||
#ifndef OSMIUM_AREA_PROBLEM_REPORTER_EXCEPTION_HPP
|
|
||||||
#define OSMIUM_AREA_PROBLEM_REPORTER_EXCEPTION_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include <osmium/area/problem_reporter_stream.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/types.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace area {
|
|
||||||
|
|
||||||
class ProblemReporterException : public ProblemReporterStream {
|
|
||||||
|
|
||||||
std::stringstream m_sstream;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
ProblemReporterException() :
|
|
||||||
ProblemReporterStream(m_sstream) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~ProblemReporterException() override = default;
|
|
||||||
|
|
||||||
void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) override {
|
|
||||||
m_sstream.str();
|
|
||||||
ProblemReporterStream::report_duplicate_node(node_id1, node_id2, location);
|
|
||||||
throw std::runtime_error(m_sstream.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_intersection(osmium::object_id_type way1_id, osmium::Location way1_seg_start, osmium::Location way1_seg_end,
|
|
||||||
osmium::object_id_type way2_id, osmium::Location way2_seg_start, osmium::Location way2_seg_end, osmium::Location intersection) override {
|
|
||||||
m_sstream.str();
|
|
||||||
ProblemReporterStream::report_intersection(way1_id, way1_seg_start, way1_seg_end, way2_id, way2_seg_start, way2_seg_end, intersection);
|
|
||||||
throw std::runtime_error(m_sstream.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_ring_not_closed(osmium::Location end1, osmium::Location end2) override {
|
|
||||||
m_sstream.str();
|
|
||||||
ProblemReporterStream::report_ring_not_closed(end1, end2);
|
|
||||||
throw std::runtime_error(m_sstream.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_role_should_be_outer(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override {
|
|
||||||
m_sstream.str();
|
|
||||||
ProblemReporterStream::report_role_should_be_outer(way_id, seg_start, seg_end);
|
|
||||||
throw std::runtime_error(m_sstream.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_role_should_be_inner(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override {
|
|
||||||
m_sstream.str();
|
|
||||||
ProblemReporterStream::report_role_should_be_inner(way_id, seg_start, seg_end);
|
|
||||||
throw std::runtime_error(m_sstream.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class ProblemReporterException
|
|
||||||
|
|
||||||
} // namespace area
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_AREA_PROBLEM_REPORTER_EXCEPTION_HPP
|
|
@ -1,139 +0,0 @@
|
|||||||
#ifndef OSMIUM_AREA_PROBLEM_REPORTER_OGR_HPP
|
|
||||||
#define OSMIUM_AREA_PROBLEM_REPORTER_OGR_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* This file contains code for reporting problems through OGR when
|
|
||||||
* assembling multipolygons.
|
|
||||||
*
|
|
||||||
* @attention If you include this file, you'll need to link with `libgdal`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include <gdalcpp.hpp>
|
|
||||||
|
|
||||||
#include <osmium/area/problem_reporter.hpp>
|
|
||||||
#include <osmium/geom/factory.hpp>
|
|
||||||
#include <osmium/geom/ogr.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/types.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace area {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report problems when assembling areas by adding them to
|
|
||||||
* layers in an OGR datasource.
|
|
||||||
*/
|
|
||||||
class ProblemReporterOGR : public ProblemReporter {
|
|
||||||
|
|
||||||
osmium::geom::OGRFactory<> m_ogr_factory;
|
|
||||||
|
|
||||||
gdalcpp::Layer m_layer_perror;
|
|
||||||
gdalcpp::Layer m_layer_lerror;
|
|
||||||
|
|
||||||
void write_point(const char* problem_type, osmium::object_id_type id1, osmium::object_id_type id2, osmium::Location location) {
|
|
||||||
gdalcpp::Feature feature(m_layer_perror, m_ogr_factory.create_point(location));
|
|
||||||
feature.set_field("id1", static_cast<double>(id1));
|
|
||||||
feature.set_field("id2", static_cast<double>(id2));
|
|
||||||
feature.set_field("problem_type", problem_type);
|
|
||||||
feature.add_to_layer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void write_line(const char* problem_type, osmium::object_id_type id1, osmium::object_id_type id2, osmium::Location loc1, osmium::Location loc2) {
|
|
||||||
std::unique_ptr<OGRPoint> ogr_point1 = m_ogr_factory.create_point(loc1);
|
|
||||||
std::unique_ptr<OGRPoint> ogr_point2 = m_ogr_factory.create_point(loc2);
|
|
||||||
std::unique_ptr<OGRLineString> ogr_linestring = std::unique_ptr<OGRLineString>(new OGRLineString());
|
|
||||||
ogr_linestring->addPoint(ogr_point1.get());
|
|
||||||
ogr_linestring->addPoint(ogr_point2.get());
|
|
||||||
|
|
||||||
gdalcpp::Feature feature(m_layer_lerror, std::move(ogr_linestring));
|
|
||||||
feature.set_field("id1", static_cast<double>(id1));
|
|
||||||
feature.set_field("id2", static_cast<double>(id2));
|
|
||||||
feature.set_field("problem_type", problem_type);
|
|
||||||
feature.add_to_layer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit ProblemReporterOGR(gdalcpp::Dataset& dataset) :
|
|
||||||
m_layer_perror(dataset, "perrors", wkbPoint),
|
|
||||||
m_layer_lerror(dataset, "lerrors", wkbLineString) {
|
|
||||||
|
|
||||||
m_layer_perror.add_field("id1", OFTReal, 10);
|
|
||||||
m_layer_perror.add_field("id2", OFTReal, 10);
|
|
||||||
m_layer_perror.add_field("problem_type", OFTString, 30);
|
|
||||||
|
|
||||||
m_layer_lerror.add_field("id1", OFTReal, 10);
|
|
||||||
m_layer_lerror.add_field("id2", OFTReal, 10);
|
|
||||||
m_layer_lerror.add_field("problem_type", OFTString, 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
~ProblemReporterOGR() override = default;
|
|
||||||
|
|
||||||
void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) override {
|
|
||||||
write_point("duplicate_node", node_id1, node_id2, location);
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_intersection(osmium::object_id_type way1_id, osmium::Location way1_seg_start, osmium::Location way1_seg_end,
|
|
||||||
osmium::object_id_type way2_id, osmium::Location way2_seg_start, osmium::Location way2_seg_end, osmium::Location intersection) override {
|
|
||||||
write_point("intersection", m_object_id, 0, intersection);
|
|
||||||
write_line("intersection", m_object_id, way1_id, way1_seg_start, way1_seg_end);
|
|
||||||
write_line("intersection", m_object_id, way2_id, way2_seg_start, way2_seg_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_ring_not_closed(osmium::Location end1, osmium::Location end2) override {
|
|
||||||
write_point("ring_not_closed", m_object_id, 0, end1);
|
|
||||||
write_point("ring_not_closed", m_object_id, 0, end2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_role_should_be_outer(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override {
|
|
||||||
write_line("role_should_be_outer", m_object_id, way_id, seg_start, seg_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_role_should_be_inner(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override {
|
|
||||||
write_line("role_should_be_inner", m_object_id, way_id, seg_start, seg_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class ProblemReporterOGR
|
|
||||||
|
|
||||||
} // namespace area
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_AREA_PROBLEM_REPORTER_OGR_HPP
|
|
@ -1,96 +0,0 @@
|
|||||||
#ifndef OSMIUM_AREA_PROBLEM_REPORTER_STREAM_HPP
|
|
||||||
#define OSMIUM_AREA_PROBLEM_REPORTER_STREAM_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
#include <osmium/area/problem_reporter.hpp>
|
|
||||||
#include <osmium/osm/item_type.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/types.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace area {
|
|
||||||
|
|
||||||
class ProblemReporterStream : public ProblemReporter {
|
|
||||||
|
|
||||||
std::ostream* m_out;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit ProblemReporterStream(std::ostream& out) :
|
|
||||||
m_out(&out) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~ProblemReporterStream() override = default;
|
|
||||||
|
|
||||||
void header(const char* msg) {
|
|
||||||
*m_out << "DATA PROBLEM: " << msg << " on " << item_type_to_char(m_object_type) << m_object_id << ": ";
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) override {
|
|
||||||
header("duplicate node");
|
|
||||||
*m_out << "node_id1=" << node_id1 << " node_id2=" << node_id2 << " location=" << location << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_intersection(osmium::object_id_type way1_id, osmium::Location way1_seg_start, osmium::Location way1_seg_end,
|
|
||||||
osmium::object_id_type way2_id, osmium::Location way2_seg_start, osmium::Location way2_seg_end, osmium::Location intersection) override {
|
|
||||||
header("intersection");
|
|
||||||
*m_out << "way1_id=" << way1_id << " way1_seg_start=" << way1_seg_start << " way1_seg_end=" << way1_seg_end
|
|
||||||
<< " way2_id=" << way2_id << " way2_seg_start=" << way2_seg_start << " way2_seg_end=" << way2_seg_end << " intersection=" << intersection << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_ring_not_closed(osmium::Location end1, osmium::Location end2) override {
|
|
||||||
header("ring not closed");
|
|
||||||
*m_out << "end1=" << end1 << " end2=" << end2 << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_role_should_be_outer(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override {
|
|
||||||
header("role should be outer");
|
|
||||||
*m_out << "way_id=" << way_id << " seg_start=" << seg_start << " seg_end=" << seg_end << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_role_should_be_inner(osmium::object_id_type way_id, osmium::Location seg_start, osmium::Location seg_end) override {
|
|
||||||
header("role should be inner");
|
|
||||||
*m_out << "way_id=" << way_id << " seg_start=" << seg_start << " seg_end=" << seg_end << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class ProblemReporterStream
|
|
||||||
|
|
||||||
} // namespace area
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_AREA_PROBLEM_REPORTER_STREAM_HPP
|
|
@ -1,877 +0,0 @@
|
|||||||
#ifndef OSMIUM_BUILDER_ATTR_HPP
|
|
||||||
#define OSMIUM_BUILDER_ATTR_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <ctime>
|
|
||||||
#include <initializer_list>
|
|
||||||
#include <iterator>
|
|
||||||
#include <string>
|
|
||||||
#include <tuple>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <osmium/builder/builder.hpp>
|
|
||||||
#include <osmium/builder/osm_object_builder.hpp>
|
|
||||||
#include <osmium/memory/buffer.hpp>
|
|
||||||
#include <osmium/osm/types.hpp>
|
|
||||||
#include <osmium/osm.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace builder {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
// workaround for bug in MSVC
|
|
||||||
|
|
||||||
template <typename THandler, typename... TTypes>
|
|
||||||
struct is_handled_by;
|
|
||||||
|
|
||||||
template <typename THandler>
|
|
||||||
struct is_handled_by<THandler> {
|
|
||||||
static constexpr bool value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename THandler, typename T, typename... TRest>
|
|
||||||
struct is_handled_by<THandler, T, TRest...> {
|
|
||||||
static constexpr bool value = std::is_base_of<typename T::handler, THandler>::value ||
|
|
||||||
is_handled_by<THandler, TRest...>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename THandler, typename... TTypes>
|
|
||||||
struct are_all_handled_by;
|
|
||||||
|
|
||||||
template <typename THandler, typename T>
|
|
||||||
struct are_all_handled_by<THandler, T> {
|
|
||||||
static constexpr bool value = std::is_base_of<typename T::handler, THandler>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename THandler, typename T, typename... TRest>
|
|
||||||
struct are_all_handled_by<THandler, T, TRest...> {
|
|
||||||
static constexpr bool value = std::is_base_of<typename T::handler, THandler>::value &&
|
|
||||||
are_all_handled_by<THandler, TRest...>::value;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
// True if Predicate matches for none of the types Ts
|
|
||||||
template <template<typename> class Predicate, typename... Ts>
|
|
||||||
struct static_none_of : std::is_same<std::tuple<std::false_type, typename Predicate<Ts>::type...>,
|
|
||||||
std::tuple<typename Predicate<Ts>::type..., std::false_type>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
// True if Predicate matches for all of the types Ts
|
|
||||||
template <template<typename> class Predicate, typename... Ts>
|
|
||||||
struct static_all_of : std::is_same<std::tuple<std::true_type, typename Predicate<Ts>::type...>,
|
|
||||||
std::tuple<typename Predicate<Ts>::type..., std::true_type>>
|
|
||||||
{};
|
|
||||||
|
|
||||||
// True if THandler is derived from the handler for at least one of the types in TTypes
|
|
||||||
template <typename THandler, typename... TTypes>
|
|
||||||
struct is_handled_by {
|
|
||||||
template <typename T>
|
|
||||||
using HasHandler = std::is_base_of<typename T::handler, THandler>;
|
|
||||||
|
|
||||||
static constexpr bool value = !static_none_of<HasHandler, TTypes...>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// True if THandler is derived from the handlers of all the types in TTypes
|
|
||||||
template <typename THandler, typename... TTypes>
|
|
||||||
struct are_all_handled_by {
|
|
||||||
template <typename T>
|
|
||||||
using HasHandler = std::is_base_of<typename T::handler, THandler>;
|
|
||||||
|
|
||||||
static constexpr bool value = static_all_of<HasHandler, TTypes...>::value;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Wraps any type, so that we can derive from it
|
|
||||||
template <typename TType>
|
|
||||||
struct type_wrapper {
|
|
||||||
|
|
||||||
using type = TType;
|
|
||||||
|
|
||||||
TType value;
|
|
||||||
|
|
||||||
constexpr explicit type_wrapper(const TType& v) :
|
|
||||||
value(v) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct type_wrapper
|
|
||||||
|
|
||||||
// Small wrapper for begin/end iterator
|
|
||||||
template <typename TType>
|
|
||||||
struct iterator_wrapper {
|
|
||||||
|
|
||||||
using type = TType;
|
|
||||||
|
|
||||||
TType first;
|
|
||||||
TType last;
|
|
||||||
|
|
||||||
constexpr iterator_wrapper(TType begin, TType end) :
|
|
||||||
first(begin),
|
|
||||||
last(end) {}
|
|
||||||
|
|
||||||
constexpr TType begin() const {
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr TType end() const {
|
|
||||||
return last;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct iterator_wrapper
|
|
||||||
|
|
||||||
|
|
||||||
struct entity_handler {};
|
|
||||||
struct object_handler;
|
|
||||||
struct node_handler;
|
|
||||||
struct tags_handler;
|
|
||||||
struct nodes_handler;
|
|
||||||
struct members_handler;
|
|
||||||
struct changeset_handler;
|
|
||||||
struct discussion_handler;
|
|
||||||
struct ring_handler;
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
#define OSMIUM_ATTRIBUTE(_handler, _name, _type) \
|
|
||||||
struct _name : public osmium::builder::detail::type_wrapper<_type> { \
|
|
||||||
using handler = osmium::builder::detail::_handler;
|
|
||||||
|
|
||||||
#define OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(_handler, _name, _type) \
|
|
||||||
OSMIUM_ATTRIBUTE(_handler, _name, _type) \
|
|
||||||
constexpr explicit _name(std::add_const<_type>::type& value) : \
|
|
||||||
type_wrapper(value) {} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OSMIUM_ATTRIBUTE_ITER(_handler, _name) \
|
|
||||||
template <typename TIterator> \
|
|
||||||
struct _name : public osmium::builder::detail::iterator_wrapper<TIterator> { \
|
|
||||||
using handler = osmium::builder::detail::_handler; \
|
|
||||||
constexpr _name(TIterator first, TIterator last) : \
|
|
||||||
osmium::builder::detail::iterator_wrapper<TIterator>(first, last) {} \
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace attr {
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(object_handler, _id, osmium::object_id_type);
|
|
||||||
OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(object_handler, _version, osmium::object_version_type);
|
|
||||||
OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(entity_handler, _uid, osmium::user_id_type);
|
|
||||||
OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(entity_handler, _cid, osmium::changeset_id_type);
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE(object_handler, _deleted, bool)
|
|
||||||
constexpr explicit _deleted(bool value = true) noexcept :
|
|
||||||
type_wrapper(value) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE(object_handler, _visible, bool)
|
|
||||||
constexpr explicit _visible(bool value = true) noexcept :
|
|
||||||
type_wrapper(value) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE(object_handler, _timestamp, osmium::Timestamp)
|
|
||||||
constexpr explicit _timestamp(const osmium::Timestamp& value) noexcept :
|
|
||||||
type_wrapper(value) {}
|
|
||||||
constexpr explicit _timestamp(time_t value) noexcept :
|
|
||||||
type_wrapper(osmium::Timestamp{value}) {}
|
|
||||||
constexpr explicit _timestamp(uint32_t value) noexcept :
|
|
||||||
type_wrapper(osmium::Timestamp{value}) {}
|
|
||||||
explicit _timestamp(const char* value) :
|
|
||||||
type_wrapper(osmium::Timestamp{value}) {}
|
|
||||||
explicit _timestamp(const std::string& value) :
|
|
||||||
type_wrapper(osmium::Timestamp{value}) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
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}) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE(entity_handler, _user, const char*)
|
|
||||||
constexpr explicit _user(const char* val) noexcept :
|
|
||||||
type_wrapper(val) {}
|
|
||||||
explicit _user(const std::string& val) noexcept :
|
|
||||||
type_wrapper(val.c_str()) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
using pair_of_cstrings = std::pair<const char* const, const char* const>;
|
|
||||||
using pair_of_strings = std::pair<const std::string&, const std::string&>;
|
|
||||||
|
|
||||||
class member_type {
|
|
||||||
|
|
||||||
osmium::item_type m_type;
|
|
||||||
osmium::object_id_type m_ref;
|
|
||||||
const char* m_role;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
constexpr member_type(osmium::item_type type, osmium::object_id_type ref, const char* role = "") noexcept :
|
|
||||||
m_type(type),
|
|
||||||
m_ref(ref),
|
|
||||||
m_role(role) {
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr osmium::item_type type() const noexcept {
|
|
||||||
return m_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr osmium::object_id_type ref() const noexcept {
|
|
||||||
return m_ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr const char* role() const noexcept {
|
|
||||||
return m_role;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class member_type
|
|
||||||
|
|
||||||
class comment_type {
|
|
||||||
|
|
||||||
osmium::Timestamp m_date;
|
|
||||||
osmium::user_id_type m_uid;
|
|
||||||
const char* m_user;
|
|
||||||
const char* m_text;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
constexpr comment_type(osmium::Timestamp date, osmium::user_id_type uid, const char* user, const char* text) noexcept :
|
|
||||||
m_date(date),
|
|
||||||
m_uid(uid),
|
|
||||||
m_user(user),
|
|
||||||
m_text(text) {
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr osmium::Timestamp date() const noexcept {
|
|
||||||
return m_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr osmium::user_id_type uid() const noexcept {
|
|
||||||
return m_uid;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr const char* user() const noexcept {
|
|
||||||
return m_user;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr const char* text() const noexcept {
|
|
||||||
return m_text;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class comment_type
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE_ITER(tags_handler, tags_from_iterator_pair);
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE_ITER(nodes_handler, nodes_from_iterator_pair);
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE_ITER(members_handler, members_from_iterator_pair);
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE_ITER(discussion_handler, comments_from_iterator_pair);
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE_ITER(ring_handler, outer_ring_from_iterator_pair);
|
|
||||||
OSMIUM_ATTRIBUTE_ITER(ring_handler, inner_ring_from_iterator_pair);
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE(tags_handler, _tag, pair_of_cstrings)
|
|
||||||
explicit _tag(const pair_of_cstrings& value) noexcept :
|
|
||||||
type_wrapper(value) {}
|
|
||||||
explicit _tag(const std::pair<const char* const, const char*>& value) :
|
|
||||||
type_wrapper(pair_of_cstrings{value.first, value.second}) {}
|
|
||||||
explicit _tag(const std::pair<const char*, const char* const>& value) :
|
|
||||||
type_wrapper(pair_of_cstrings{value.first, value.second}) {}
|
|
||||||
explicit _tag(const std::pair<const char*, const char*>& value) :
|
|
||||||
type_wrapper(pair_of_cstrings{value.first, value.second}) {}
|
|
||||||
explicit _tag(const pair_of_strings& value) :
|
|
||||||
type_wrapper(std::make_pair(value.first.c_str(), value.second.c_str())) {}
|
|
||||||
explicit _tag(const char* key, const char* val) :
|
|
||||||
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())) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TTagIterator>
|
|
||||||
inline constexpr detail::tags_from_iterator_pair<TTagIterator> _tags(TTagIterator first, TTagIterator last) {
|
|
||||||
return detail::tags_from_iterator_pair<TTagIterator>(first, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TContainer>
|
|
||||||
inline detail::tags_from_iterator_pair<typename TContainer::const_iterator> _tags(const TContainer& container) {
|
|
||||||
return detail::tags_from_iterator_pair<typename TContainer::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
using tag_ilist = std::initializer_list<std::pair<const char*, const char*>>;
|
|
||||||
inline detail::tags_from_iterator_pair<tag_ilist::const_iterator> _tags(const tag_ilist& container) {
|
|
||||||
return detail::tags_from_iterator_pair<tag_ilist::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE(nodes_handler, _node, osmium::NodeRef)
|
|
||||||
constexpr explicit _node(osmium::object_id_type value) noexcept :
|
|
||||||
type_wrapper(NodeRef{value}) {}
|
|
||||||
constexpr explicit _node(const NodeRef& value) noexcept :
|
|
||||||
type_wrapper(value) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TIdIterator>
|
|
||||||
inline constexpr detail::nodes_from_iterator_pair<TIdIterator> _nodes(TIdIterator first, TIdIterator last) {
|
|
||||||
return detail::nodes_from_iterator_pair<TIdIterator>(first, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TContainer>
|
|
||||||
inline detail::nodes_from_iterator_pair<typename TContainer::const_iterator> _nodes(const TContainer& container) {
|
|
||||||
return detail::nodes_from_iterator_pair<typename TContainer::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
using object_id_ilist = std::initializer_list<osmium::object_id_type>;
|
|
||||||
inline detail::nodes_from_iterator_pair<object_id_ilist::const_iterator> _nodes(const object_id_ilist& container) {
|
|
||||||
return detail::nodes_from_iterator_pair<object_id_ilist::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
using node_ref_ilist = std::initializer_list<osmium::NodeRef>;
|
|
||||||
inline detail::nodes_from_iterator_pair<node_ref_ilist::const_iterator> _nodes(const node_ref_ilist& container) {
|
|
||||||
return detail::nodes_from_iterator_pair<node_ref_ilist::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE(members_handler, _member, member_type)
|
|
||||||
constexpr explicit _member(const member_type& value) noexcept :
|
|
||||||
type_wrapper(value) {}
|
|
||||||
constexpr explicit _member(osmium::item_type type, osmium::object_id_type id) noexcept :
|
|
||||||
type_wrapper({type, id}) {}
|
|
||||||
constexpr explicit _member(osmium::item_type type, osmium::object_id_type id, const char* role) noexcept :
|
|
||||||
type_wrapper({type, id, role}) {}
|
|
||||||
explicit _member(osmium::item_type type, osmium::object_id_type id, const std::string& role) noexcept :
|
|
||||||
type_wrapper({type, id, role.c_str()}) {}
|
|
||||||
explicit _member(const osmium::RelationMember& member) noexcept :
|
|
||||||
type_wrapper({member.type(), member.ref(), member.role()}) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TMemberIterator>
|
|
||||||
inline constexpr detail::members_from_iterator_pair<TMemberIterator> _members(TMemberIterator first, TMemberIterator last) {
|
|
||||||
return detail::members_from_iterator_pair<TMemberIterator>(first, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TContainer>
|
|
||||||
inline detail::members_from_iterator_pair<typename TContainer::const_iterator> _members(const TContainer& container) {
|
|
||||||
return detail::members_from_iterator_pair<typename TContainer::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
using member_ilist = std::initializer_list<member_type>;
|
|
||||||
inline detail::members_from_iterator_pair<member_ilist::const_iterator> _members(const member_ilist& container) {
|
|
||||||
return detail::members_from_iterator_pair<member_ilist::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _num_changes, osmium::num_changes_type);
|
|
||||||
OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _num_comments, osmium::num_comments_type);
|
|
||||||
OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _created_at, osmium::Timestamp);
|
|
||||||
OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _closed_at, osmium::Timestamp);
|
|
||||||
|
|
||||||
OSMIUM_ATTRIBUTE(discussion_handler, _comment, comment_type)
|
|
||||||
constexpr explicit _comment(const comment_type& value) noexcept :
|
|
||||||
type_wrapper(value) {}
|
|
||||||
explicit _comment(const osmium::ChangesetComment& comment) noexcept :
|
|
||||||
type_wrapper({comment.date(), comment.uid(), comment.user(), comment.text()}) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TCommentIterator>
|
|
||||||
inline constexpr detail::comments_from_iterator_pair<TCommentIterator> _comments(TCommentIterator first, TCommentIterator last) {
|
|
||||||
return detail::comments_from_iterator_pair<TCommentIterator>(first, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TContainer>
|
|
||||||
inline detail::comments_from_iterator_pair<typename TContainer::const_iterator> _comments(const TContainer& container) {
|
|
||||||
return detail::comments_from_iterator_pair<typename TContainer::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
using comment_ilist = std::initializer_list<comment_type>;
|
|
||||||
inline detail::comments_from_iterator_pair<comment_ilist::const_iterator> _comments(const comment_ilist& container) {
|
|
||||||
return detail::comments_from_iterator_pair<comment_ilist::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename TIdIterator>
|
|
||||||
inline constexpr detail::outer_ring_from_iterator_pair<TIdIterator> _outer_ring(TIdIterator first, TIdIterator last) {
|
|
||||||
return detail::outer_ring_from_iterator_pair<TIdIterator>(first, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TContainer>
|
|
||||||
inline detail::outer_ring_from_iterator_pair<typename TContainer::const_iterator> _outer_ring(const TContainer& container) {
|
|
||||||
return detail::outer_ring_from_iterator_pair<typename TContainer::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
using object_id_ilist = std::initializer_list<osmium::object_id_type>;
|
|
||||||
inline detail::outer_ring_from_iterator_pair<object_id_ilist::const_iterator> _outer_ring(const object_id_ilist& container) {
|
|
||||||
return detail::outer_ring_from_iterator_pair<object_id_ilist::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
using node_ref_ilist = std::initializer_list<osmium::NodeRef>;
|
|
||||||
inline detail::outer_ring_from_iterator_pair<node_ref_ilist::const_iterator> _outer_ring(const node_ref_ilist& container) {
|
|
||||||
return detail::outer_ring_from_iterator_pair<node_ref_ilist::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TIdIterator>
|
|
||||||
inline constexpr detail::inner_ring_from_iterator_pair<TIdIterator> _inner_ring(TIdIterator first, TIdIterator last) {
|
|
||||||
return detail::inner_ring_from_iterator_pair<TIdIterator>(first, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TContainer>
|
|
||||||
inline detail::inner_ring_from_iterator_pair<typename TContainer::const_iterator> _inner_ring(const TContainer& container) {
|
|
||||||
return detail::inner_ring_from_iterator_pair<typename TContainer::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
using object_id_ilist = std::initializer_list<osmium::object_id_type>;
|
|
||||||
inline detail::inner_ring_from_iterator_pair<object_id_ilist::const_iterator> _inner_ring(const object_id_ilist& container) {
|
|
||||||
return detail::inner_ring_from_iterator_pair<object_id_ilist::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
using node_ref_ilist = std::initializer_list<osmium::NodeRef>;
|
|
||||||
inline detail::inner_ring_from_iterator_pair<node_ref_ilist::const_iterator> _inner_ring(const node_ref_ilist& container) {
|
|
||||||
return detail::inner_ring_from_iterator_pair<node_ref_ilist::const_iterator>(std::begin(container), std::end(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace attr
|
|
||||||
|
|
||||||
#undef OSMIUM_ATTRIBUTE_ITER
|
|
||||||
#undef OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR
|
|
||||||
#undef OSMIUM_ATTRIBUTE
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
struct changeset_handler : public entity_handler {
|
|
||||||
|
|
||||||
template <typename TDummy>
|
|
||||||
static void set_value(osmium::Changeset&, const TDummy&) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::Changeset& changeset, attr::_cid id) noexcept {
|
|
||||||
changeset.set_id(id.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::Changeset& changeset, attr::_num_changes num_changes) noexcept {
|
|
||||||
changeset.set_num_changes(num_changes.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::Changeset& changeset, attr::_num_comments num_comments) noexcept {
|
|
||||||
changeset.set_num_comments(num_comments.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::Changeset& changeset, attr::_created_at created_at) noexcept {
|
|
||||||
changeset.set_created_at(created_at.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::Changeset& changeset, attr::_closed_at closed_at) noexcept {
|
|
||||||
changeset.set_closed_at(closed_at.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::Changeset& changeset, attr::_uid uid) noexcept {
|
|
||||||
changeset.set_uid(uid.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct object_handler : public entity_handler {
|
|
||||||
|
|
||||||
template <typename TDummy>
|
|
||||||
static void set_value(osmium::OSMObject&, const TDummy&) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::OSMObject& object, attr::_id id) noexcept {
|
|
||||||
object.set_id(id.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::OSMObject& object, attr::_version version) noexcept {
|
|
||||||
object.set_version(version.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::OSMObject& object, attr::_visible visible) noexcept {
|
|
||||||
object.set_visible(visible.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::OSMObject& object, attr::_deleted deleted) noexcept {
|
|
||||||
object.set_deleted(deleted.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::OSMObject& object, attr::_timestamp timestamp) noexcept {
|
|
||||||
object.set_timestamp(timestamp.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::OSMObject& object, attr::_cid changeset) noexcept {
|
|
||||||
object.set_changeset(changeset.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(osmium::OSMObject& object, attr::_uid uid) noexcept {
|
|
||||||
object.set_uid(uid.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // object_handler
|
|
||||||
|
|
||||||
struct node_handler : public object_handler {
|
|
||||||
|
|
||||||
using object_handler::set_value;
|
|
||||||
|
|
||||||
static void set_value(osmium::Node& node, attr::_location location) noexcept {
|
|
||||||
node.set_location(location.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // node_handler
|
|
||||||
|
|
||||||
template <typename THandler, typename TBuilder, typename... TArgs>
|
|
||||||
inline void add_basic(TBuilder& builder, const TArgs&... args) noexcept {
|
|
||||||
(void)std::initializer_list<int>{
|
|
||||||
(THandler::set_value(builder.object(), args), 0)...
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==============================================================
|
|
||||||
|
|
||||||
template <typename... TArgs>
|
|
||||||
inline constexpr const char* get_user(const attr::_user& user, const TArgs&...) noexcept {
|
|
||||||
return user.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline constexpr const char* get_user() noexcept {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TFirst, typename... TRest>
|
|
||||||
inline constexpr typename std::enable_if<!std::is_same<attr::_user, TFirst>::value, const char*>::type
|
|
||||||
get_user(const TFirst&, const TRest&... args) noexcept {
|
|
||||||
return get_user(args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TBuilder, typename... TArgs>
|
|
||||||
inline void add_user(TBuilder& builder, const TArgs&... args) {
|
|
||||||
builder.add_user(get_user(args...));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==============================================================
|
|
||||||
|
|
||||||
struct tags_handler {
|
|
||||||
|
|
||||||
template <typename TDummy>
|
|
||||||
static void set_value(TagListBuilder&, const TDummy&) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(TagListBuilder& builder, const attr::_tag& tag) {
|
|
||||||
builder.add_tag(tag.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TIterator>
|
|
||||||
static void set_value(TagListBuilder& builder, const attr::detail::tags_from_iterator_pair<TIterator>& tags) {
|
|
||||||
for (const auto& tag : tags) {
|
|
||||||
builder.add_tag(tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct tags_handler
|
|
||||||
|
|
||||||
struct nodes_handler {
|
|
||||||
|
|
||||||
template <typename TDummy>
|
|
||||||
static void set_value(WayNodeListBuilder&, const TDummy&) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(WayNodeListBuilder& builder, const attr::_node& node_ref) {
|
|
||||||
builder.add_node_ref(node_ref.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TIterator>
|
|
||||||
static void set_value(WayNodeListBuilder& builder, const attr::detail::nodes_from_iterator_pair<TIterator>& nodes) {
|
|
||||||
for (const auto& ref : nodes) {
|
|
||||||
builder.add_node_ref(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct nodes_handler
|
|
||||||
|
|
||||||
struct members_handler {
|
|
||||||
|
|
||||||
template <typename TDummy>
|
|
||||||
static void set_value(RelationMemberListBuilder&, const TDummy&) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(RelationMemberListBuilder& builder, const attr::_member& member) {
|
|
||||||
builder.add_member(member.value.type(), member.value.ref(), member.value.role());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TIterator>
|
|
||||||
static void set_value(RelationMemberListBuilder& builder, const attr::detail::members_from_iterator_pair<TIterator>& members) {
|
|
||||||
for (const auto& member : members) {
|
|
||||||
builder.add_member(member.type(), member.ref(), member.role());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct members_handler
|
|
||||||
|
|
||||||
struct discussion_handler {
|
|
||||||
|
|
||||||
template <typename TDummy>
|
|
||||||
static void set_value(ChangesetDiscussionBuilder&, const TDummy&) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_value(ChangesetDiscussionBuilder& builder, const attr::_comment& comment) {
|
|
||||||
builder.add_comment(comment.value.date(), comment.value.uid(), comment.value.user());
|
|
||||||
builder.add_comment_text(comment.value.text());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TIterator>
|
|
||||||
static void set_value(ChangesetDiscussionBuilder& builder, const attr::detail::comments_from_iterator_pair<TIterator>& comments) {
|
|
||||||
for (const auto& comment : comments) {
|
|
||||||
builder.add_comment(comment.date(), comment.uid(), comment.user());
|
|
||||||
builder.add_comment_text(comment.text());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct discussion_handler
|
|
||||||
|
|
||||||
struct ring_handler {
|
|
||||||
|
|
||||||
template <typename TDummy>
|
|
||||||
static void set_value(AreaBuilder&, const TDummy&) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TIterator>
|
|
||||||
static void set_value(AreaBuilder& parent, const attr::detail::outer_ring_from_iterator_pair<TIterator>& nodes) {
|
|
||||||
OuterRingBuilder builder(parent.buffer(), &parent);
|
|
||||||
for (const auto& ref : nodes) {
|
|
||||||
builder.add_node_ref(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TIterator>
|
|
||||||
static void set_value(AreaBuilder& parent, const attr::detail::inner_ring_from_iterator_pair<TIterator>& nodes) {
|
|
||||||
InnerRingBuilder builder(parent.buffer(), &parent);
|
|
||||||
for (const auto& ref : nodes) {
|
|
||||||
builder.add_node_ref(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct ring_handler
|
|
||||||
|
|
||||||
// ==============================================================
|
|
||||||
|
|
||||||
template <typename TBuilder, typename THandler, typename... TArgs>
|
|
||||||
inline typename std::enable_if<!is_handled_by<THandler, TArgs...>::value>::type
|
|
||||||
add_list(osmium::builder::Builder&, const TArgs&...) noexcept {
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
(void)std::initializer_list<int>{
|
|
||||||
(THandler::set_value(builder, args), 0)...
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
struct any_node_handlers : public node_handler, public tags_handler {};
|
|
||||||
struct any_way_handlers : public object_handler, public tags_handler, public nodes_handler {};
|
|
||||||
struct any_relation_handlers : public object_handler, public tags_handler, public members_handler {};
|
|
||||||
struct any_area_handlers : public object_handler, public tags_handler, public ring_handler {};
|
|
||||||
struct any_changeset_handlers : public changeset_handler, public tags_handler, public discussion_handler {};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a node using the given arguments and add it to the given buffer.
|
|
||||||
*
|
|
||||||
* @param buffer The buffer to which the node will be added.
|
|
||||||
* @param args The attributes of the node.
|
|
||||||
* @returns The position in the buffer where this node was added.
|
|
||||||
*/
|
|
||||||
template <typename... TArgs>
|
|
||||||
inline size_t add_node(osmium::memory::Buffer& buffer, const TArgs&... args) {
|
|
||||||
static_assert(sizeof...(args) > 0, "add_node() must have buffer and at least one additional argument");
|
|
||||||
static_assert(detail::are_all_handled_by<detail::any_node_handlers, TArgs...>::value, "Attribute not allowed in add_node()");
|
|
||||||
|
|
||||||
NodeBuilder builder(buffer);
|
|
||||||
|
|
||||||
detail::add_basic<detail::node_handler>(builder, args...);
|
|
||||||
detail::add_user(builder, args...);
|
|
||||||
detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
|
|
||||||
|
|
||||||
return buffer.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a way using the given arguments and add it to the given buffer.
|
|
||||||
*
|
|
||||||
* @param buffer The buffer to which the way will be added.
|
|
||||||
* @param args The attributes of the way.
|
|
||||||
* @returns The position in the buffer where this way was added.
|
|
||||||
*/
|
|
||||||
template <typename... TArgs>
|
|
||||||
inline size_t add_way(osmium::memory::Buffer& buffer, const TArgs&... args) {
|
|
||||||
static_assert(sizeof...(args) > 0, "add_way() must have buffer and at least one additional argument");
|
|
||||||
static_assert(detail::are_all_handled_by<detail::any_way_handlers, TArgs...>::value, "Attribute not allowed in add_way()");
|
|
||||||
|
|
||||||
WayBuilder builder(buffer);
|
|
||||||
|
|
||||||
detail::add_basic<detail::object_handler>(builder, args...);
|
|
||||||
detail::add_user(builder, args...);
|
|
||||||
detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
|
|
||||||
detail::add_list<WayNodeListBuilder, detail::nodes_handler>(builder, args...);
|
|
||||||
|
|
||||||
return buffer.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a relation using the given arguments and add it to the given buffer.
|
|
||||||
*
|
|
||||||
* @param buffer The buffer to which the relation will be added.
|
|
||||||
* @param args The attributes of the relation.
|
|
||||||
* @returns The position in the buffer where this relation was added.
|
|
||||||
*/
|
|
||||||
template <typename... TArgs>
|
|
||||||
inline size_t add_relation(osmium::memory::Buffer& buffer, const TArgs&... args) {
|
|
||||||
static_assert(sizeof...(args) > 0, "add_relation() must have buffer and at least one additional argument");
|
|
||||||
static_assert(detail::are_all_handled_by<detail::any_relation_handlers, TArgs...>::value, "Attribute not allowed in add_relation()");
|
|
||||||
|
|
||||||
RelationBuilder builder(buffer);
|
|
||||||
|
|
||||||
detail::add_basic<detail::object_handler>(builder, args...);
|
|
||||||
detail::add_user(builder, args...);
|
|
||||||
detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
|
|
||||||
detail::add_list<RelationMemberListBuilder, detail::members_handler>(builder, args...);
|
|
||||||
|
|
||||||
return buffer.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a changeset using the given arguments and add it to the given buffer.
|
|
||||||
*
|
|
||||||
* @param buffer The buffer to which the changeset will be added.
|
|
||||||
* @param args The attributes of the changeset.
|
|
||||||
* @returns The position in the buffer where this changeset was added.
|
|
||||||
*/
|
|
||||||
template <typename... TArgs>
|
|
||||||
inline size_t add_changeset(osmium::memory::Buffer& buffer, const TArgs&... args) {
|
|
||||||
static_assert(sizeof...(args) > 0, "add_changeset() must have buffer and at least one additional argument");
|
|
||||||
static_assert(detail::are_all_handled_by<detail::any_changeset_handlers, TArgs...>::value, "Attribute not allowed in add_changeset()");
|
|
||||||
|
|
||||||
ChangesetBuilder builder(buffer);
|
|
||||||
|
|
||||||
detail::add_basic<detail::changeset_handler>(builder, args...);
|
|
||||||
detail::add_user(builder, args...);
|
|
||||||
detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
|
|
||||||
detail::add_list<ChangesetDiscussionBuilder, detail::discussion_handler>(builder, args...);
|
|
||||||
|
|
||||||
return buffer.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a area using the given arguments and add it to the given buffer.
|
|
||||||
*
|
|
||||||
* @param buffer The buffer to which the area will be added.
|
|
||||||
* @param args The attributes of the area.
|
|
||||||
* @returns The position in the buffer where this area was added.
|
|
||||||
*/
|
|
||||||
template <typename... TArgs>
|
|
||||||
inline size_t add_area(osmium::memory::Buffer& buffer, const TArgs&... args) {
|
|
||||||
static_assert(sizeof...(args) > 0, "add_area() must have buffer and at least one additional argument");
|
|
||||||
static_assert(detail::are_all_handled_by<detail::any_area_handlers, TArgs...>::value, "Attribute not allowed in add_area()");
|
|
||||||
|
|
||||||
AreaBuilder builder(buffer);
|
|
||||||
|
|
||||||
detail::add_basic<detail::object_handler>(builder, args...);
|
|
||||||
detail::add_user(builder, args...);
|
|
||||||
detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
|
|
||||||
|
|
||||||
(void)std::initializer_list<int>{
|
|
||||||
(detail::ring_handler::set_value(builder, args), 0)...
|
|
||||||
};
|
|
||||||
|
|
||||||
return buffer.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a WayNodeList using the given arguments and add it to the given buffer.
|
|
||||||
*
|
|
||||||
* @param buffer The buffer to which the list will be added.
|
|
||||||
* @param args The contents of the list.
|
|
||||||
* @returns The position in the buffer where this list was added.
|
|
||||||
*/
|
|
||||||
template <typename... TArgs>
|
|
||||||
inline size_t add_way_node_list(osmium::memory::Buffer& buffer, const TArgs&... args) {
|
|
||||||
static_assert(sizeof...(args) > 0, "add_way_node_list() must have buffer and at least one additional argument");
|
|
||||||
static_assert(detail::are_all_handled_by<detail::nodes_handler, TArgs...>::value, "Attribute not allowed in add_way_node_list()");
|
|
||||||
|
|
||||||
{
|
|
||||||
WayNodeListBuilder builder(buffer);
|
|
||||||
(void)std::initializer_list<int>{
|
|
||||||
(detail::nodes_handler::set_value(builder, args), 0)...
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a TagList using the given arguments and add it to the given buffer.
|
|
||||||
*
|
|
||||||
* @param buffer The buffer to which the list will be added.
|
|
||||||
* @param args The contents of the list.
|
|
||||||
* @returns The position in the buffer where this list was added.
|
|
||||||
*/
|
|
||||||
template <typename... TArgs>
|
|
||||||
inline size_t add_tag_list(osmium::memory::Buffer& buffer, const TArgs&... args) {
|
|
||||||
static_assert(sizeof...(args) > 0, "add_tag_list() must have buffer and at least one additional argument");
|
|
||||||
static_assert(detail::are_all_handled_by<detail::tags_handler, TArgs...>::value, "Attribute not allowed in add_tag_list()");
|
|
||||||
|
|
||||||
{
|
|
||||||
TagListBuilder builder(buffer);
|
|
||||||
(void)std::initializer_list<int>{
|
|
||||||
(detail::tags_handler::set_value(builder, args), 0)...
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace builder
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_BUILDER_ATTR_HPP
|
|
@ -1,237 +0,0 @@
|
|||||||
#ifndef OSMIUM_BUILDER_BUILDER_HPP
|
|
||||||
#define OSMIUM_BUILDER_BUILDER_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstring>
|
|
||||||
#include <new>
|
|
||||||
#include <string>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include <osmium/memory/buffer.hpp>
|
|
||||||
#include <osmium/memory/item.hpp>
|
|
||||||
#include <osmium/osm/types.hpp>
|
|
||||||
#include <osmium/util/cast.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Classes for building OSM objects and other items in buffers
|
|
||||||
*/
|
|
||||||
namespace builder {
|
|
||||||
|
|
||||||
class Builder {
|
|
||||||
|
|
||||||
osmium::memory::Buffer& m_buffer;
|
|
||||||
Builder* m_parent;
|
|
||||||
size_t m_item_offset;
|
|
||||||
|
|
||||||
Builder(const Builder&) = delete;
|
|
||||||
Builder(Builder&&) = delete;
|
|
||||||
|
|
||||||
Builder& operator=(const Builder&) = delete;
|
|
||||||
Builder& operator=(Builder&&) = delete;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
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_buffer.reserve_space(size);
|
|
||||||
assert(buffer.is_aligned());
|
|
||||||
if (m_parent) {
|
|
||||||
m_parent->add_size(size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~Builder() = default;
|
|
||||||
|
|
||||||
osmium::memory::Item& item() const {
|
|
||||||
return *reinterpret_cast<osmium::memory::Item*>(m_buffer.data() + m_item_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add padding to buffer (if needed) to align data properly.
|
|
||||||
*
|
|
||||||
* This calculates how many padding bytes are needed and adds
|
|
||||||
* as many zero bytes to the buffer. It also adds this number
|
|
||||||
* to the size of the current item (if the "self" param is
|
|
||||||
* true) and recursively to all the parent items.
|
|
||||||
*
|
|
||||||
* @param self If true add number of padding bytes to size
|
|
||||||
* of current item. Size is always added to
|
|
||||||
* parent item (if any).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void add_padding(bool self = false) {
|
|
||||||
auto padding = osmium::memory::align_bytes - (size() % osmium::memory::align_bytes);
|
|
||||||
if (padding != osmium::memory::align_bytes) {
|
|
||||||
std::fill_n(m_buffer.reserve_space(padding), padding, 0);
|
|
||||||
if (self) {
|
|
||||||
add_size(padding);
|
|
||||||
} else if (m_parent) {
|
|
||||||
m_parent->add_size(padding);
|
|
||||||
assert(m_parent->size() % osmium::memory::align_bytes == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_size(uint32_t size) {
|
|
||||||
item().add_size(size);
|
|
||||||
if (m_parent) {
|
|
||||||
m_parent->add_size(size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t size() const noexcept {
|
|
||||||
return item().byte_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_item(const osmium::memory::Item* item) {
|
|
||||||
unsigned char* target = m_buffer.reserve_space(item->padded_size());
|
|
||||||
std::copy_n(reinterpret_cast<const unsigned char*>(item), item->padded_size(), target);
|
|
||||||
add_size(item->padded_size());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reserve space for an object of class T in buffer and return
|
|
||||||
* pointer to it.
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
T* reserve_space_for() {
|
|
||||||
assert(m_buffer.is_aligned());
|
|
||||||
return reinterpret_cast<T*>(m_buffer.reserve_space(sizeof(T)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append data to buffer.
|
|
||||||
*
|
|
||||||
* @param data Pointer to data.
|
|
||||||
* @param length Length of data in bytes. If data is a
|
|
||||||
* \0-terminated string, length must contain the
|
|
||||||
* \0 byte.
|
|
||||||
* @returns The number of bytes appended (length).
|
|
||||||
*/
|
|
||||||
osmium::memory::item_size_type append(const char* data, const osmium::memory::item_size_type length) {
|
|
||||||
unsigned char* target = m_buffer.reserve_space(length);
|
|
||||||
std::copy_n(reinterpret_cast<const unsigned char*>(data), length, target);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append \0-terminated string to buffer.
|
|
||||||
*
|
|
||||||
* @param str \0-terminated string.
|
|
||||||
* @returns The number of bytes appended (strlen(str) + 1).
|
|
||||||
*/
|
|
||||||
osmium::memory::item_size_type append(const char* str) {
|
|
||||||
return append(str, static_cast<osmium::memory::item_size_type>(std::strlen(str) + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append '\0' to the buffer.
|
|
||||||
*
|
|
||||||
* @returns The number of bytes appended (always 1).
|
|
||||||
*/
|
|
||||||
osmium::memory::item_size_type append_zero() {
|
|
||||||
*m_buffer.reserve_space(1) = '\0';
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the buffer this builder is using.
|
|
||||||
osmium::memory::Buffer& buffer() noexcept {
|
|
||||||
return m_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class Builder
|
|
||||||
|
|
||||||
template <typename TItem>
|
|
||||||
class ObjectBuilder : public Builder {
|
|
||||||
|
|
||||||
static_assert(std::is_base_of<osmium::memory::Item, TItem>::value, "ObjectBuilder can only build objects derived from osmium::memory::Item");
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit ObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
|
|
||||||
Builder(buffer, parent, sizeof(TItem)) {
|
|
||||||
new (&item()) TItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
TItem& object() noexcept {
|
|
||||||
return static_cast<TItem&>(item());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add user name to buffer.
|
|
||||||
*
|
|
||||||
* @param user Pointer to user name.
|
|
||||||
* @param length Length of user name (without \0 termination).
|
|
||||||
*/
|
|
||||||
void add_user(const char* user, const string_size_type length) {
|
|
||||||
object().set_user_size(length + 1);
|
|
||||||
add_size(append(user, length) + append_zero());
|
|
||||||
add_padding(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add user name to buffer.
|
|
||||||
*
|
|
||||||
* @param user Pointer to \0-terminated user name.
|
|
||||||
*/
|
|
||||||
void add_user(const char* user) {
|
|
||||||
add_user(user, static_cast_with_assert<string_size_type>(std::strlen(user)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add user name to buffer.
|
|
||||||
*
|
|
||||||
* @param user User name.
|
|
||||||
*/
|
|
||||||
void add_user(const std::string& user) {
|
|
||||||
add_user(user.data(), static_cast_with_assert<string_size_type>(user.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class ObjectBuilder
|
|
||||||
|
|
||||||
} // namespace builder
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_BUILDER_BUILDER_HPP
|
|
@ -1,120 +0,0 @@
|
|||||||
#ifndef OSMIUM_BUILDER_BUILDER_HELPER_HPP
|
|
||||||
#define OSMIUM_BUILDER_BUILDER_HELPER_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <initializer_list>
|
|
||||||
#include <functional>
|
|
||||||
#include <map>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <osmium/builder/osm_object_builder.hpp>
|
|
||||||
#include <osmium/memory/buffer.hpp>
|
|
||||||
#include <osmium/util/compatibility.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
class NodeRef;
|
|
||||||
class TagList;
|
|
||||||
class WayNodeList;
|
|
||||||
|
|
||||||
namespace builder {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* Use osmium::builder::add_way_node_list() instead.
|
|
||||||
*/
|
|
||||||
OSMIUM_DEPRECATED inline const osmium::WayNodeList& build_way_node_list(osmium::memory::Buffer& buffer, const std::initializer_list<osmium::NodeRef>& nodes) {
|
|
||||||
size_t pos = buffer.committed();
|
|
||||||
{
|
|
||||||
osmium::builder::WayNodeListBuilder wnl_builder(buffer);
|
|
||||||
for (const auto& node_ref : nodes) {
|
|
||||||
wnl_builder.add_node_ref(node_ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buffer.commit();
|
|
||||||
return buffer.get<const osmium::WayNodeList>(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* Use osmium::builder::add_tag_list() instead.
|
|
||||||
*/
|
|
||||||
inline const osmium::TagList& build_tag_list(osmium::memory::Buffer& buffer, const std::initializer_list<std::pair<const char*, const char*>>& tags) {
|
|
||||||
size_t pos = buffer.committed();
|
|
||||||
{
|
|
||||||
osmium::builder::TagListBuilder tl_builder(buffer);
|
|
||||||
for (const auto& p : tags) {
|
|
||||||
tl_builder.add_tag(p.first, p.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buffer.commit();
|
|
||||||
return buffer.get<const osmium::TagList>(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* Use osmium::builder::add_tag_list() instead.
|
|
||||||
*/
|
|
||||||
inline const osmium::TagList& build_tag_list_from_map(osmium::memory::Buffer& buffer, const std::map<const char*, const char*>& tags) {
|
|
||||||
size_t pos = buffer.committed();
|
|
||||||
{
|
|
||||||
osmium::builder::TagListBuilder tl_builder(buffer);
|
|
||||||
for (const auto& p : tags) {
|
|
||||||
tl_builder.add_tag(p.first, p.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buffer.commit();
|
|
||||||
return buffer.get<const osmium::TagList>(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* Use osmium::builder::add_tag_list() instead.
|
|
||||||
*/
|
|
||||||
inline const osmium::TagList& build_tag_list_from_func(osmium::memory::Buffer& buffer, std::function<void(osmium::builder::TagListBuilder&)> func) {
|
|
||||||
size_t pos = buffer.committed();
|
|
||||||
{
|
|
||||||
osmium::builder::TagListBuilder tl_builder(buffer);
|
|
||||||
func(tl_builder);
|
|
||||||
}
|
|
||||||
buffer.commit();
|
|
||||||
return buffer.get<const osmium::TagList>(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace builder
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_BUILDER_BUILDER_HELPER_HPP
|
|
@ -1,407 +0,0 @@
|
|||||||
#ifndef OSMIUM_BUILDER_OSM_OBJECT_BUILDER_HPP
|
|
||||||
#define OSMIUM_BUILDER_OSM_OBJECT_BUILDER_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstring>
|
|
||||||
#include <initializer_list>
|
|
||||||
#include <limits>
|
|
||||||
#include <new>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <osmium/builder/builder.hpp>
|
|
||||||
#include <osmium/osm.hpp>
|
|
||||||
#include <osmium/osm/item_type.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/node_ref.hpp>
|
|
||||||
#include <osmium/osm/object.hpp>
|
|
||||||
#include <osmium/osm/tag.hpp>
|
|
||||||
#include <osmium/osm/types.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace memory {
|
|
||||||
class Buffer;
|
|
||||||
} // namespace memory
|
|
||||||
|
|
||||||
namespace builder {
|
|
||||||
|
|
||||||
class TagListBuilder : public ObjectBuilder<TagList> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit TagListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
|
|
||||||
ObjectBuilder<TagList>(buffer, parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~TagListBuilder() {
|
|
||||||
add_padding();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add tag to buffer.
|
|
||||||
*
|
|
||||||
* @param key Tag key (0-terminated string).
|
|
||||||
* @param value Tag value (0-terminated string).
|
|
||||||
*/
|
|
||||||
void add_tag(const char* key, const char* value) {
|
|
||||||
if (std::strlen(key) > osmium::max_osm_string_length) {
|
|
||||||
throw std::length_error("OSM tag key is too long");
|
|
||||||
}
|
|
||||||
if (std::strlen(value) > osmium::max_osm_string_length) {
|
|
||||||
throw std::length_error("OSM tag value is too long");
|
|
||||||
}
|
|
||||||
add_size(append(key) + append(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add tag to buffer.
|
|
||||||
*
|
|
||||||
* @param key Pointer to tag key.
|
|
||||||
* @param key_length Length of key (not including the \0 byte).
|
|
||||||
* @param value Pointer to tag value.
|
|
||||||
* @param value_length Length of value (not including the \0 byte).
|
|
||||||
*/
|
|
||||||
void add_tag(const char* key, const size_t key_length, const char* value, const size_t value_length) {
|
|
||||||
if (key_length > osmium::max_osm_string_length) {
|
|
||||||
throw std::length_error("OSM tag key is too long");
|
|
||||||
}
|
|
||||||
if (value_length > osmium::max_osm_string_length) {
|
|
||||||
throw std::length_error("OSM tag value is too long");
|
|
||||||
}
|
|
||||||
add_size(append(key, osmium::memory::item_size_type(key_length)) + append_zero() +
|
|
||||||
append(value, osmium::memory::item_size_type(value_length)) + append_zero());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add tag to buffer.
|
|
||||||
*
|
|
||||||
* @param key Tag key.
|
|
||||||
* @param value Tag value.
|
|
||||||
*/
|
|
||||||
void add_tag(const std::string& key, const std::string& value) {
|
|
||||||
if (key.size() > osmium::max_osm_string_length) {
|
|
||||||
throw std::length_error("OSM tag key is too long");
|
|
||||||
}
|
|
||||||
if (value.size() > osmium::max_osm_string_length) {
|
|
||||||
throw std::length_error("OSM tag value is too long");
|
|
||||||
}
|
|
||||||
add_size(append(key.data(), osmium::memory::item_size_type(key.size()) + 1) +
|
|
||||||
append(value.data(), osmium::memory::item_size_type(value.size()) + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add tag to buffer.
|
|
||||||
*
|
|
||||||
* @param tag Tag.
|
|
||||||
*/
|
|
||||||
void add_tag(const osmium::Tag& tag) {
|
|
||||||
add_size(append(tag.key()) + append(tag.value()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add tag to buffer.
|
|
||||||
*
|
|
||||||
* @param tag Pair of key/value 0-terminated strings.
|
|
||||||
*/
|
|
||||||
void add_tag(const std::pair<const char* const, const char* const>& tag) {
|
|
||||||
add_tag(tag.first, tag.second);
|
|
||||||
}
|
|
||||||
void add_tag(const std::pair<const char* const, const char*>& tag) {
|
|
||||||
add_tag(tag.first, tag.second);
|
|
||||||
}
|
|
||||||
void add_tag(const std::pair<const char*, const char* const>& tag) {
|
|
||||||
add_tag(tag.first, tag.second);
|
|
||||||
}
|
|
||||||
void add_tag(const std::pair<const char*, const char*>& tag) {
|
|
||||||
add_tag(tag.first, tag.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add tag to buffer.
|
|
||||||
*
|
|
||||||
* @param tag Pair of std::string references.
|
|
||||||
*/
|
|
||||||
void add_tag(const std::pair<const std::string&, const std::string&>& tag) {
|
|
||||||
add_tag(tag.first, tag.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class TagListBuilder
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class NodeRefListBuilder : public ObjectBuilder<T> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit NodeRefListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
|
|
||||||
ObjectBuilder<T>(buffer, parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~NodeRefListBuilder() {
|
|
||||||
static_cast<Builder*>(this)->add_padding();
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_node_ref(const NodeRef& node_ref) {
|
|
||||||
new (static_cast<Builder*>(this)->reserve_space_for<osmium::NodeRef>()) osmium::NodeRef(node_ref);
|
|
||||||
static_cast<Builder*>(this)->add_size(sizeof(osmium::NodeRef));
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_node_ref(const object_id_type ref, const osmium::Location& location = Location{}) {
|
|
||||||
add_node_ref(NodeRef(ref, location));
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class NodeRefListBuilder
|
|
||||||
|
|
||||||
typedef NodeRefListBuilder<WayNodeList> WayNodeListBuilder;
|
|
||||||
typedef NodeRefListBuilder<OuterRing> OuterRingBuilder;
|
|
||||||
typedef NodeRefListBuilder<InnerRing> InnerRingBuilder;
|
|
||||||
|
|
||||||
class RelationMemberListBuilder : public ObjectBuilder<RelationMemberList> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add role to buffer.
|
|
||||||
*
|
|
||||||
* @param member Relation member object where the length of the role
|
|
||||||
* will be set.
|
|
||||||
* @param role The role.
|
|
||||||
* @param length Length of role (without \0 termination).
|
|
||||||
* @throws std:length_error If role is longer than osmium::max_osm_string_length
|
|
||||||
*/
|
|
||||||
void add_role(osmium::RelationMember& member, const char* role, const size_t length) {
|
|
||||||
if (length > osmium::max_osm_string_length) {
|
|
||||||
throw std::length_error("OSM relation member role is too long");
|
|
||||||
}
|
|
||||||
member.set_role_size(osmium::string_size_type(length) + 1);
|
|
||||||
add_size(append(role, osmium::memory::item_size_type(length)) + append_zero());
|
|
||||||
add_padding(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit RelationMemberListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
|
|
||||||
ObjectBuilder<RelationMemberList>(buffer, parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~RelationMemberListBuilder() {
|
|
||||||
add_padding();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a member to the relation.
|
|
||||||
*
|
|
||||||
* @param type The type (node, way, or relation).
|
|
||||||
* @param ref The ID of the member.
|
|
||||||
* @param role The role of the member.
|
|
||||||
* @param role_length Length of the role (without \0 termination).
|
|
||||||
* @param full_member Optional pointer to the member object. If it
|
|
||||||
* is available a copy will be added to the
|
|
||||||
* relation.
|
|
||||||
* @throws std:length_error If role_length is greater than
|
|
||||||
* osmium::max_osm_string_length
|
|
||||||
*/
|
|
||||||
void add_member(osmium::item_type type, object_id_type ref, const char* role, const size_t role_length, const osmium::OSMObject* full_member = nullptr) {
|
|
||||||
osmium::RelationMember* member = reserve_space_for<osmium::RelationMember>();
|
|
||||||
new (member) osmium::RelationMember(ref, type, full_member != nullptr);
|
|
||||||
add_size(sizeof(RelationMember));
|
|
||||||
add_role(*member, role, role_length);
|
|
||||||
if (full_member) {
|
|
||||||
add_item(full_member);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a member to the relation.
|
|
||||||
*
|
|
||||||
* @param type The type (node, way, or relation).
|
|
||||||
* @param ref The ID of the member.
|
|
||||||
* @param role The role of the member (\0 terminated string).
|
|
||||||
* @param full_member Optional pointer to the member object. If it
|
|
||||||
* is available a copy will be added to the
|
|
||||||
* relation.
|
|
||||||
* @throws std:length_error If role is longer than osmium::max_osm_string_length
|
|
||||||
*/
|
|
||||||
void add_member(osmium::item_type type, object_id_type ref, const char* role, const osmium::OSMObject* full_member = nullptr) {
|
|
||||||
add_member(type, ref, role, std::strlen(role), full_member);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a member to the relation.
|
|
||||||
*
|
|
||||||
* @param type The type (node, way, or relation).
|
|
||||||
* @param ref The ID of the member.
|
|
||||||
* @param role The role of the member.
|
|
||||||
* @param full_member Optional pointer to the member object. If it
|
|
||||||
* is available a copy will be added to the
|
|
||||||
* relation.
|
|
||||||
* @throws std:length_error If role is longer than osmium::max_osm_string_length
|
|
||||||
*/
|
|
||||||
void add_member(osmium::item_type type, object_id_type ref, const std::string& role, const osmium::OSMObject* full_member = nullptr) {
|
|
||||||
add_member(type, ref, role.data(), role.size(), full_member);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class RelationMemberListBuilder
|
|
||||||
|
|
||||||
class ChangesetDiscussionBuilder : public ObjectBuilder<ChangesetDiscussion> {
|
|
||||||
|
|
||||||
osmium::ChangesetComment* m_comment = nullptr;
|
|
||||||
|
|
||||||
void add_user(osmium::ChangesetComment& comment, const char* user, const size_t length) {
|
|
||||||
if (length > osmium::max_osm_string_length) {
|
|
||||||
throw std::length_error("OSM user name is too long");
|
|
||||||
}
|
|
||||||
comment.set_user_size(osmium::string_size_type(length) + 1);
|
|
||||||
add_size(append(user, osmium::memory::item_size_type(length)) + append_zero());
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_text(osmium::ChangesetComment& comment, const char* text, const size_t length) {
|
|
||||||
// XXX There is no limit on the length of a comment text. We
|
|
||||||
// limit it here to 2^16-2 characters, because that's all that
|
|
||||||
// will fit into our internal data structure. This is not ideal,
|
|
||||||
// and will have to be discussed and cleared up.
|
|
||||||
if (length > std::numeric_limits<osmium::string_size_type>::max() - 1) {
|
|
||||||
throw std::length_error("OSM changeset comment is too long");
|
|
||||||
}
|
|
||||||
comment.set_text_size(osmium::string_size_type(length) + 1);
|
|
||||||
add_size(append(text, osmium::memory::item_size_type(length)) + append_zero());
|
|
||||||
add_padding(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit ChangesetDiscussionBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
|
|
||||||
ObjectBuilder<ChangesetDiscussion>(buffer, parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~ChangesetDiscussionBuilder() {
|
|
||||||
assert(!m_comment && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
|
|
||||||
add_padding();
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_comment(osmium::Timestamp date, osmium::user_id_type uid, const char* user) {
|
|
||||||
assert(!m_comment && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
|
|
||||||
m_comment = reserve_space_for<osmium::ChangesetComment>();
|
|
||||||
new (m_comment) osmium::ChangesetComment(date, uid);
|
|
||||||
add_size(sizeof(ChangesetComment));
|
|
||||||
add_user(*m_comment, user, std::strlen(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_comment_text(const char* text) {
|
|
||||||
assert(m_comment && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
|
|
||||||
add_text(*m_comment, text, std::strlen(text));
|
|
||||||
m_comment = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_comment_text(const std::string& text) {
|
|
||||||
assert(m_comment && "You have to always call both add_comment() and then add_comment_text() in that order for each comment!");
|
|
||||||
add_text(*m_comment, text.c_str(), text.size());
|
|
||||||
m_comment = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class ChangesetDiscussionBuilder
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class OSMObjectBuilder : public ObjectBuilder<T> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit OSMObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
|
|
||||||
ObjectBuilder<T>(buffer, parent) {
|
|
||||||
static_cast<Builder*>(this)->reserve_space_for<string_size_type>();
|
|
||||||
static_cast<Builder*>(this)->add_size(sizeof(string_size_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_tags(const std::initializer_list<std::pair<const char*, const char*>>& tags) {
|
|
||||||
osmium::builder::TagListBuilder tl_builder(static_cast<Builder*>(this)->buffer(), this);
|
|
||||||
for (const auto& p : tags) {
|
|
||||||
tl_builder.add_tag(p.first, p.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class OSMObjectBuilder
|
|
||||||
|
|
||||||
typedef OSMObjectBuilder<osmium::Node> NodeBuilder;
|
|
||||||
typedef OSMObjectBuilder<osmium::Relation> RelationBuilder;
|
|
||||||
|
|
||||||
class WayBuilder : public OSMObjectBuilder<osmium::Way> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit WayBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
|
|
||||||
OSMObjectBuilder<osmium::Way>(buffer, parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_node_refs(const std::initializer_list<osmium::NodeRef>& nodes) {
|
|
||||||
osmium::builder::WayNodeListBuilder builder(buffer(), this);
|
|
||||||
for (const auto& node_ref : nodes) {
|
|
||||||
builder.add_node_ref(node_ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class WayBuilder
|
|
||||||
|
|
||||||
class AreaBuilder : public OSMObjectBuilder<osmium::Area> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit AreaBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
|
|
||||||
OSMObjectBuilder<osmium::Area>(buffer, parent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize area attributes from the attributes of the given object.
|
|
||||||
*/
|
|
||||||
void initialize_from_object(const osmium::OSMObject& source) {
|
|
||||||
osmium::Area& area = object();
|
|
||||||
area.set_id(osmium::object_id_to_area_id(source.id(), source.type()));
|
|
||||||
area.set_version(source.version());
|
|
||||||
area.set_changeset(source.changeset());
|
|
||||||
area.set_timestamp(source.timestamp());
|
|
||||||
area.set_visible(source.visible());
|
|
||||||
area.set_uid(source.uid());
|
|
||||||
|
|
||||||
add_user(source.user());
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class AreaBuilder
|
|
||||||
|
|
||||||
typedef ObjectBuilder<osmium::Changeset> ChangesetBuilder;
|
|
||||||
|
|
||||||
} // namespace builder
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_BUILDER_OSM_OBJECT_BUILDER_HPP
|
|
@ -1,66 +0,0 @@
|
|||||||
#ifndef OSMIUM_DIFF_HANDLER_HPP
|
|
||||||
#define OSMIUM_DIFF_HANDLER_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <osmium/osm/diff_object.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Osmium diff handlers provide access to differences between OSM object versions
|
|
||||||
*/
|
|
||||||
namespace diff_handler {
|
|
||||||
|
|
||||||
class DiffHandler {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DiffHandler() = default;
|
|
||||||
|
|
||||||
void node(const osmium::DiffNode&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void way(const osmium::DiffWay&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation(const osmium::DiffRelation&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class DiffHandler
|
|
||||||
|
|
||||||
} // namespace diff_handler
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_DIFF_HANDLER_HPP
|
|
@ -1,135 +0,0 @@
|
|||||||
#ifndef OSMIUM_DIFF_ITERATOR_HPP
|
|
||||||
#define OSMIUM_DIFF_ITERATOR_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <iterator>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include <osmium/osm/diff_object.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
class OSMObject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An input iterator wrapping any iterator over OSMObjects. When
|
|
||||||
* dereferenced it will yield DiffObject objects pointing to the
|
|
||||||
* underlying OSMObjects.
|
|
||||||
*/
|
|
||||||
template <typename TBasicIterator>
|
|
||||||
class DiffIterator : public std::iterator<std::input_iterator_tag, const osmium::DiffObject> {
|
|
||||||
|
|
||||||
static_assert(std::is_base_of<osmium::OSMObject, typename TBasicIterator::value_type>::value, "TBasicIterator::value_type must derive from osmium::OSMObject");
|
|
||||||
|
|
||||||
TBasicIterator m_prev;
|
|
||||||
TBasicIterator m_curr;
|
|
||||||
TBasicIterator m_next;
|
|
||||||
|
|
||||||
const TBasicIterator m_end;
|
|
||||||
|
|
||||||
mutable osmium::DiffObject m_diff;
|
|
||||||
|
|
||||||
void set_diff() const noexcept {
|
|
||||||
assert(m_curr != m_end);
|
|
||||||
|
|
||||||
bool use_curr_for_prev = m_prev->type() != m_curr->type() || m_prev->id() != m_curr->id();
|
|
||||||
bool use_curr_for_next = m_next == m_end || m_next->type() != m_curr->type() || m_next->id() != m_curr->id();
|
|
||||||
|
|
||||||
m_diff = std::move(osmium::DiffObject{
|
|
||||||
*(use_curr_for_prev ? m_curr : m_prev),
|
|
||||||
*m_curr,
|
|
||||||
*(use_curr_for_next ? m_curr : m_next)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DiffIterator(TBasicIterator begin, TBasicIterator end) :
|
|
||||||
m_prev(begin),
|
|
||||||
m_curr(begin),
|
|
||||||
m_next(begin == end ? begin : ++begin),
|
|
||||||
m_end(std::move(end)),
|
|
||||||
m_diff() {
|
|
||||||
}
|
|
||||||
|
|
||||||
DiffIterator& operator++() {
|
|
||||||
m_prev = std::move(m_curr);
|
|
||||||
m_curr = m_next;
|
|
||||||
|
|
||||||
if (m_next != m_end) {
|
|
||||||
++m_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
DiffIterator operator++(int) {
|
|
||||||
DiffIterator tmp(*this);
|
|
||||||
operator++();
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const DiffIterator& rhs) const noexcept {
|
|
||||||
return m_curr == rhs.m_curr && m_end == rhs.m_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const DiffIterator& rhs) const noexcept {
|
|
||||||
return !(*this == rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
reference operator*() const noexcept {
|
|
||||||
set_diff();
|
|
||||||
return m_diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer operator->() const noexcept {
|
|
||||||
set_diff();
|
|
||||||
return &m_diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class DiffIterator
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a DiffIterator based on the given iterators.
|
|
||||||
*/
|
|
||||||
template <typename TBasicIterator>
|
|
||||||
inline DiffIterator<TBasicIterator> make_diff_iterator(TBasicIterator begin,
|
|
||||||
TBasicIterator end) {
|
|
||||||
return DiffIterator<TBasicIterator>{begin, end};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_DIFF_ITERATOR_HPP
|
|
@ -1,104 +0,0 @@
|
|||||||
#ifndef OSMIUM_DIFF_VISITOR_HPP
|
|
||||||
#define OSMIUM_DIFF_VISITOR_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <osmium/diff_iterator.hpp>
|
|
||||||
#include <osmium/io/input_iterator.hpp>
|
|
||||||
#include <osmium/memory/buffer.hpp>
|
|
||||||
#include <osmium/osm/diff_object.hpp>
|
|
||||||
#include <osmium/osm/item_type.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <typename THandler>
|
|
||||||
inline void apply_diff_iterator_recurse(const osmium::DiffObject& diff, THandler& handler) {
|
|
||||||
switch (diff.type()) {
|
|
||||||
case osmium::item_type::node:
|
|
||||||
handler.node(static_cast<const osmium::DiffNode&>(diff));
|
|
||||||
break;
|
|
||||||
case osmium::item_type::way:
|
|
||||||
handler.way(static_cast<const osmium::DiffWay&>(diff));
|
|
||||||
break;
|
|
||||||
case osmium::item_type::relation:
|
|
||||||
handler.relation(static_cast<const osmium::DiffRelation&>(diff));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw osmium::unknown_type();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename THandler, typename... TRest>
|
|
||||||
inline void apply_diff_iterator_recurse(const osmium::DiffObject& diff, THandler& handler, TRest&... more) {
|
|
||||||
apply_diff_iterator_recurse(diff, handler);
|
|
||||||
apply_diff_iterator_recurse(diff, more...);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <typename TIterator, typename... THandlers>
|
|
||||||
inline void apply_diff(TIterator it, TIterator end, THandlers&... handlers) {
|
|
||||||
using diff_iterator = osmium::DiffIterator<TIterator>;
|
|
||||||
|
|
||||||
diff_iterator dit(it, end);
|
|
||||||
diff_iterator dend(end, end);
|
|
||||||
|
|
||||||
for (; dit != dend; ++dit) {
|
|
||||||
detail::apply_diff_iterator_recurse(*dit, handlers...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class OSMObject;
|
|
||||||
|
|
||||||
template <typename TSource, typename... THandlers>
|
|
||||||
inline void apply_diff(TSource& source, THandlers&... handlers) {
|
|
||||||
apply_diff(osmium::io::InputIterator<TSource, osmium::OSMObject> {source},
|
|
||||||
osmium::io::InputIterator<TSource, osmium::OSMObject> {},
|
|
||||||
handlers...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... THandlers>
|
|
||||||
inline void apply_diff(osmium::memory::Buffer& buffer, THandlers&... handlers) {
|
|
||||||
apply_diff(buffer.begin(), buffer.end(), handlers...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... THandlers>
|
|
||||||
inline void apply_diff(const osmium::memory::Buffer& buffer, THandlers&... handlers) {
|
|
||||||
apply_diff(buffer.cbegin(), buffer.cend(), handlers...);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_DIFF_VISITOR_HPP
|
|
@ -1,190 +0,0 @@
|
|||||||
#ifndef OSMIUM_DYNAMIC_HANDLER_HPP
|
|
||||||
#define OSMIUM_DYNAMIC_HANDLER_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <osmium/fwd.hpp>
|
|
||||||
#include <osmium/handler.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace handler {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
class HandlerWrapperBase {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
virtual ~HandlerWrapperBase() {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void node(const osmium::Node&) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void way(const osmium::Way&) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void relation(const osmium::Relation&) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void area(const osmium::Area&) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void changeset(const osmium::Changeset&) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void flush() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class HandlerWrapperBase
|
|
||||||
|
|
||||||
|
|
||||||
// The following uses trick from
|
|
||||||
// http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence
|
|
||||||
// to either call handler style functions or visitor style operator().
|
|
||||||
|
|
||||||
#define OSMIUM_DYNAMIC_HANDLER_DISPATCH(_name_, _type_) \
|
|
||||||
template <typename THandler> \
|
|
||||||
auto _name_##_dispatch(THandler& handler, const osmium::_type_& object, int) -> decltype(handler._name_(object), void()) { \
|
|
||||||
handler._name_(object); \
|
|
||||||
} \
|
|
||||||
template <typename THandler> \
|
|
||||||
auto _name_##_dispatch(THandler& handler, const osmium::_type_& object, long) -> decltype(handler(object), void()) { \
|
|
||||||
handler(object); \
|
|
||||||
}
|
|
||||||
|
|
||||||
OSMIUM_DYNAMIC_HANDLER_DISPATCH(node, Node)
|
|
||||||
OSMIUM_DYNAMIC_HANDLER_DISPATCH(way, Way)
|
|
||||||
OSMIUM_DYNAMIC_HANDLER_DISPATCH(relation, Relation)
|
|
||||||
OSMIUM_DYNAMIC_HANDLER_DISPATCH(changeset, Changeset)
|
|
||||||
OSMIUM_DYNAMIC_HANDLER_DISPATCH(area, Area)
|
|
||||||
|
|
||||||
template <typename THandler>
|
|
||||||
auto flush_dispatch(THandler& handler, int) -> decltype(handler.flush(), void()) {
|
|
||||||
handler.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename THandler>
|
|
||||||
void flush_dispatch(THandler&, long) {}
|
|
||||||
|
|
||||||
template <typename THandler>
|
|
||||||
class HandlerWrapper : public HandlerWrapperBase {
|
|
||||||
|
|
||||||
THandler m_handler;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
template <typename... TArgs>
|
|
||||||
HandlerWrapper(TArgs&&... args) :
|
|
||||||
m_handler(std::forward<TArgs>(args)...) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void node(const osmium::Node& node) final {
|
|
||||||
node_dispatch(m_handler, node, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void way(const osmium::Way& way) final {
|
|
||||||
way_dispatch(m_handler, way, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation(const osmium::Relation& relation) final {
|
|
||||||
relation_dispatch(m_handler, relation, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void area(const osmium::Area& area) final {
|
|
||||||
area_dispatch(m_handler, area, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void changeset(const osmium::Changeset& changeset) final {
|
|
||||||
changeset_dispatch(m_handler, changeset, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush() final {
|
|
||||||
flush_dispatch(m_handler, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class HandlerWrapper
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
class DynamicHandler : public osmium::handler::Handler {
|
|
||||||
|
|
||||||
typedef std::unique_ptr<osmium::handler::detail::HandlerWrapperBase> impl_ptr;
|
|
||||||
impl_ptr m_impl;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DynamicHandler() :
|
|
||||||
m_impl(impl_ptr(new osmium::handler::detail::HandlerWrapperBase)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename THandler, typename... TArgs>
|
|
||||||
void set(TArgs&&... args) {
|
|
||||||
m_impl = impl_ptr(new osmium::handler::detail::HandlerWrapper<THandler>(std::forward<TArgs>(args)...));
|
|
||||||
}
|
|
||||||
|
|
||||||
void node(const osmium::Node& node) {
|
|
||||||
m_impl->node(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void way(const osmium::Way& way) {
|
|
||||||
m_impl->way(way);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation(const osmium::Relation& relation) {
|
|
||||||
m_impl->relation(relation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void area(const osmium::Area& area) {
|
|
||||||
m_impl->area(area);
|
|
||||||
}
|
|
||||||
|
|
||||||
void changeset(const osmium::Changeset& changeset) {
|
|
||||||
m_impl->changeset(changeset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush() {
|
|
||||||
m_impl->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class DynamicHandler
|
|
||||||
|
|
||||||
} // namespace handler
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_DYNAMIC_HANDLER_HPP
|
|
@ -1,137 +0,0 @@
|
|||||||
#ifndef OSMIUM_EXPERIMENTAL_FLEX_READER_HPP
|
|
||||||
#define OSMIUM_EXPERIMENTAL_FLEX_READER_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <osmium/area/assembler.hpp>
|
|
||||||
#include <osmium/area/multipolygon_collector.hpp>
|
|
||||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
|
||||||
#include <osmium/io/file.hpp>
|
|
||||||
#include <osmium/io/header.hpp>
|
|
||||||
#include <osmium/io/reader.hpp>
|
|
||||||
#include <osmium/memory/buffer.hpp>
|
|
||||||
#include <osmium/osm/entity_bits.hpp>
|
|
||||||
#include <osmium/visitor.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Experimental code that is not "officially" supported.
|
|
||||||
*/
|
|
||||||
namespace experimental {
|
|
||||||
|
|
||||||
template <typename TLocationHandler>
|
|
||||||
class FlexReader {
|
|
||||||
|
|
||||||
bool m_with_areas;
|
|
||||||
osmium::osm_entity_bits::type m_entities;
|
|
||||||
|
|
||||||
TLocationHandler& m_location_handler;
|
|
||||||
|
|
||||||
osmium::io::Reader m_reader;
|
|
||||||
osmium::area::Assembler::config_type m_assembler_config;
|
|
||||||
osmium::area::MultipolygonCollector<osmium::area::Assembler> m_collector;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit FlexReader(const osmium::io::File& file, TLocationHandler& location_handler, osmium::osm_entity_bits::type entities = osmium::osm_entity_bits::nwr) :
|
|
||||||
m_with_areas((entities & osmium::osm_entity_bits::area) != 0),
|
|
||||||
m_entities((entities & ~osmium::osm_entity_bits::area) | (m_with_areas ? osmium::osm_entity_bits::node | osmium::osm_entity_bits::way : osmium::osm_entity_bits::nothing)),
|
|
||||||
m_location_handler(location_handler),
|
|
||||||
m_reader(file, m_entities),
|
|
||||||
m_assembler_config(),
|
|
||||||
m_collector(m_assembler_config)
|
|
||||||
{
|
|
||||||
m_location_handler.ignore_errors();
|
|
||||||
if (m_with_areas) {
|
|
||||||
osmium::io::Reader reader(file, osmium::osm_entity_bits::relation);
|
|
||||||
m_collector.read_relations(reader);
|
|
||||||
reader.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit FlexReader(const std::string& filename, TLocationHandler& location_handler, osmium::osm_entity_bits::type entities = osmium::osm_entity_bits::nwr) :
|
|
||||||
FlexReader(osmium::io::File(filename), location_handler, entities) {
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit FlexReader(const char* filename, TLocationHandler& location_handler, osmium::osm_entity_bits::type entities = osmium::osm_entity_bits::nwr) :
|
|
||||||
FlexReader(osmium::io::File(filename), location_handler, entities) {
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::memory::Buffer read() {
|
|
||||||
osmium::memory::Buffer buffer = m_reader.read();
|
|
||||||
|
|
||||||
if (buffer) {
|
|
||||||
if (m_with_areas) {
|
|
||||||
std::vector<osmium::memory::Buffer> area_buffers;
|
|
||||||
osmium::apply(buffer, m_location_handler, m_collector.handler([&area_buffers](osmium::memory::Buffer&& area_buffer) {
|
|
||||||
area_buffers.push_back(std::move(area_buffer));
|
|
||||||
}));
|
|
||||||
for (const osmium::memory::Buffer& b : area_buffers) {
|
|
||||||
buffer.add_buffer(b);
|
|
||||||
buffer.commit();
|
|
||||||
}
|
|
||||||
} else if (m_entities & (osmium::osm_entity_bits::node | osmium::osm_entity_bits::way)) {
|
|
||||||
osmium::apply(buffer, m_location_handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::io::Header header() {
|
|
||||||
return m_reader.header();
|
|
||||||
}
|
|
||||||
|
|
||||||
void close() {
|
|
||||||
return m_reader.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool eof() const {
|
|
||||||
return m_reader.eof();
|
|
||||||
}
|
|
||||||
|
|
||||||
const osmium::area::MultipolygonCollector<osmium::area::Assembler>& collector() const {
|
|
||||||
return m_collector;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class FlexReader
|
|
||||||
|
|
||||||
} // namespace experimental
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_EXPERIMENTAL_FLEX_READER_HPP
|
|
70
third_party/libosmium/include/osmium/fwd.hpp
vendored
70
third_party/libosmium/include/osmium/fwd.hpp
vendored
@ -1,70 +0,0 @@
|
|||||||
#ifndef OSMIUM_FWD_HPP
|
|
||||||
#define OSMIUM_FWD_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* This file contains forward declarations for commonly used Osmium classes.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
class Area;
|
|
||||||
class Box;
|
|
||||||
class Changeset;
|
|
||||||
class ChangesetComment;
|
|
||||||
class ChangesetDiscussion;
|
|
||||||
class InnerRing;
|
|
||||||
class Location;
|
|
||||||
class Node;
|
|
||||||
class NodeRef;
|
|
||||||
class NodeRefList;
|
|
||||||
class OSMEntity;
|
|
||||||
class OSMObject;
|
|
||||||
class OuterRing;
|
|
||||||
class Relation;
|
|
||||||
class RelationMemberList;
|
|
||||||
class Segment;
|
|
||||||
class Tag;
|
|
||||||
class TagList;
|
|
||||||
class Timestamp;
|
|
||||||
class Way;
|
|
||||||
class WayNodeList;
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_FWD_HPP
|
|
@ -1,96 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_COORDINATES_HPP
|
|
||||||
#define OSMIUM_GEOM_COORDINATES_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/util/double.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
struct Coordinates {
|
|
||||||
|
|
||||||
double x;
|
|
||||||
double y;
|
|
||||||
|
|
||||||
explicit Coordinates(double cx, double cy) noexcept : x(cx), y(cy) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Coordinates(const osmium::Location& location) : x(location.lon()), y(location.lat()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void append_to_string(std::string& s, const char infix, int precision) const {
|
|
||||||
osmium::util::double2string(s, x, precision);
|
|
||||||
s += infix;
|
|
||||||
osmium::util::double2string(s, y, precision);
|
|
||||||
}
|
|
||||||
|
|
||||||
void append_to_string(std::string& s, const char prefix, const char infix, const char suffix, int precision) const {
|
|
||||||
s += prefix;
|
|
||||||
append_to_string(s, infix, precision);
|
|
||||||
s += suffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct coordinates
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare whether two Coordinates are identical. Might not give the
|
|
||||||
* right result if the coordinates have been the result of some
|
|
||||||
* calculation that introduced rounding errors.
|
|
||||||
*/
|
|
||||||
inline bool operator==(const Coordinates& lhs, const Coordinates& rhs) noexcept {
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
|
||||||
return lhs.x == rhs.x && lhs.y == rhs.y;
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const Coordinates& lhs, const Coordinates& rhs) noexcept {
|
|
||||||
return ! operator==(lhs, rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TChar, typename TTraits>
|
|
||||||
inline std::basic_ostream<TChar, TTraits>& operator<<(std::basic_ostream<TChar, TTraits>& out, const Coordinates& c) {
|
|
||||||
return out << '(' << c.x << ',' << c.y << ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_COORDINATES_HPP
|
|
@ -1,419 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_FACTORY_HPP
|
|
||||||
#define OSMIUM_GEOM_FACTORY_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <osmium/geom/coordinates.hpp>
|
|
||||||
#include <osmium/memory/collection.hpp>
|
|
||||||
#include <osmium/memory/item.hpp>
|
|
||||||
#include <osmium/osm/area.hpp>
|
|
||||||
#include <osmium/osm/item_type.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/node.hpp>
|
|
||||||
#include <osmium/osm/node_ref.hpp>
|
|
||||||
#include <osmium/osm/way.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception thrown when an invalid geometry is encountered. An example
|
|
||||||
* would be a linestring with less than two points.
|
|
||||||
*/
|
|
||||||
class geometry_error : public std::runtime_error {
|
|
||||||
|
|
||||||
std::string m_message;
|
|
||||||
osmium::object_id_type m_id;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit geometry_error(const std::string& message, const char* object_type = "", osmium::object_id_type id = 0) :
|
|
||||||
std::runtime_error(message),
|
|
||||||
m_message(message),
|
|
||||||
m_id(id) {
|
|
||||||
if (m_id != 0) {
|
|
||||||
m_message += " (";
|
|
||||||
m_message += object_type;
|
|
||||||
m_message += "_id=";
|
|
||||||
m_message += std::to_string(m_id);
|
|
||||||
m_message += ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_id(const char* object_type, osmium::object_id_type id) {
|
|
||||||
if (m_id == 0 && id != 0) {
|
|
||||||
m_message += " (";
|
|
||||||
m_message += object_type;
|
|
||||||
m_message += "_id=";
|
|
||||||
m_message += std::to_string(id);
|
|
||||||
m_message += ")";
|
|
||||||
}
|
|
||||||
m_id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::object_id_type id() const noexcept {
|
|
||||||
return m_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* what() const noexcept override {
|
|
||||||
return m_message.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct geometry_error
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Everything related to geometry handling.
|
|
||||||
*/
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Which nodes of a way to use for a linestring.
|
|
||||||
*/
|
|
||||||
enum class use_nodes : bool {
|
|
||||||
unique = true, ///< Remove consecutive nodes with same location.
|
|
||||||
all = false ///< Use all nodes.
|
|
||||||
}; // enum class use_nodes
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Which direction the linestring created from a way
|
|
||||||
* should have.
|
|
||||||
*/
|
|
||||||
enum class direction : bool {
|
|
||||||
backward = true, ///< Linestring has reverse direction.
|
|
||||||
forward = false ///< Linestring has same direction as way.
|
|
||||||
}; // enum class direction
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This pseudo projection just returns its WGS84 input unchanged.
|
|
||||||
* Used as a template parameter if a real projection is not needed.
|
|
||||||
*/
|
|
||||||
class IdentityProjection {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Coordinates operator()(osmium::Location location) const {
|
|
||||||
return Coordinates{location.lon(), location.lat()};
|
|
||||||
}
|
|
||||||
|
|
||||||
int epsg() const noexcept {
|
|
||||||
return 4326;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string proj_string() const {
|
|
||||||
return "+proj=longlat +datum=WGS84 +no_defs";
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class IdentityProjection
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Geometry factory.
|
|
||||||
*/
|
|
||||||
template <typename TGeomImpl, typename TProjection = IdentityProjection>
|
|
||||||
class GeometryFactory {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add all points of an outer or inner ring to a multipolygon.
|
|
||||||
*/
|
|
||||||
void add_points(const osmium::OuterRing& nodes) {
|
|
||||||
osmium::Location last_location;
|
|
||||||
for (const osmium::NodeRef& node_ref : nodes) {
|
|
||||||
if (last_location != node_ref.location()) {
|
|
||||||
last_location = node_ref.location();
|
|
||||||
m_impl.multipolygon_add_location(m_projection(last_location));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TProjection m_projection;
|
|
||||||
TGeomImpl m_impl;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for default initialized projection.
|
|
||||||
*/
|
|
||||||
template <typename... TArgs>
|
|
||||||
explicit GeometryFactory<TGeomImpl, TProjection>(TArgs&&... args) :
|
|
||||||
m_projection(),
|
|
||||||
m_impl(std::forward<TArgs>(args)...) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for explicitly initialized projection. Note that the
|
|
||||||
* projection is moved into the GeometryFactory.
|
|
||||||
*/
|
|
||||||
template <typename... TArgs>
|
|
||||||
explicit GeometryFactory<TGeomImpl, TProjection>(TProjection&& projection, TArgs&&... args) :
|
|
||||||
m_projection(std::move(projection)),
|
|
||||||
m_impl(std::forward<TArgs>(args)...) {
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef TProjection projection_type;
|
|
||||||
typedef typename TGeomImpl::point_type point_type;
|
|
||||||
typedef typename TGeomImpl::linestring_type linestring_type;
|
|
||||||
typedef typename TGeomImpl::polygon_type polygon_type;
|
|
||||||
typedef typename TGeomImpl::multipolygon_type multipolygon_type;
|
|
||||||
typedef typename TGeomImpl::ring_type ring_type;
|
|
||||||
|
|
||||||
int epsg() const {
|
|
||||||
return m_projection.epsg();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string proj_string() const {
|
|
||||||
return m_projection.proj_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Point */
|
|
||||||
|
|
||||||
point_type create_point(const osmium::Location& location) const {
|
|
||||||
return m_impl.make_point(m_projection(location));
|
|
||||||
}
|
|
||||||
|
|
||||||
point_type create_point(const osmium::Node& node) {
|
|
||||||
try {
|
|
||||||
return create_point(node.location());
|
|
||||||
} catch (osmium::geometry_error& e) {
|
|
||||||
e.set_id("node", node.id());
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
point_type create_point(const osmium::NodeRef& node_ref) {
|
|
||||||
try {
|
|
||||||
return create_point(node_ref.location());
|
|
||||||
} catch (osmium::geometry_error& e) {
|
|
||||||
e.set_id("node", node_ref.ref());
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LineString */
|
|
||||||
|
|
||||||
void linestring_start() {
|
|
||||||
m_impl.linestring_start();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TIter>
|
|
||||||
size_t fill_linestring(TIter it, TIter end) {
|
|
||||||
size_t num_points = 0;
|
|
||||||
for (; it != end; ++it, ++num_points) {
|
|
||||||
m_impl.linestring_add_location(m_projection(it->location()));
|
|
||||||
}
|
|
||||||
return num_points;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TIter>
|
|
||||||
size_t fill_linestring_unique(TIter it, TIter end) {
|
|
||||||
size_t num_points = 0;
|
|
||||||
osmium::Location last_location;
|
|
||||||
for (; it != end; ++it) {
|
|
||||||
if (last_location != it->location()) {
|
|
||||||
last_location = it->location();
|
|
||||||
m_impl.linestring_add_location(m_projection(last_location));
|
|
||||||
++num_points;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return num_points;
|
|
||||||
}
|
|
||||||
|
|
||||||
linestring_type linestring_finish(size_t num_points) {
|
|
||||||
return m_impl.linestring_finish(num_points);
|
|
||||||
}
|
|
||||||
|
|
||||||
linestring_type create_linestring(const osmium::WayNodeList& wnl, use_nodes un = use_nodes::unique, direction dir = direction::forward) {
|
|
||||||
linestring_start();
|
|
||||||
size_t num_points = 0;
|
|
||||||
|
|
||||||
if (un == use_nodes::unique) {
|
|
||||||
osmium::Location last_location;
|
|
||||||
switch (dir) {
|
|
||||||
case direction::forward:
|
|
||||||
num_points = fill_linestring_unique(wnl.cbegin(), wnl.cend());
|
|
||||||
break;
|
|
||||||
case direction::backward:
|
|
||||||
num_points = fill_linestring_unique(wnl.crbegin(), wnl.crend());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (dir) {
|
|
||||||
case direction::forward:
|
|
||||||
num_points = fill_linestring(wnl.cbegin(), wnl.cend());
|
|
||||||
break;
|
|
||||||
case direction::backward:
|
|
||||||
num_points = fill_linestring(wnl.crbegin(), wnl.crend());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_points < 2) {
|
|
||||||
throw osmium::geometry_error("need at least two points for linestring");
|
|
||||||
}
|
|
||||||
|
|
||||||
return linestring_finish(num_points);
|
|
||||||
}
|
|
||||||
|
|
||||||
linestring_type create_linestring(const osmium::Way& way, use_nodes un=use_nodes::unique, direction dir=direction::forward) {
|
|
||||||
try {
|
|
||||||
return create_linestring(way.nodes(), un, dir);
|
|
||||||
} catch (osmium::geometry_error& e) {
|
|
||||||
e.set_id("way", way.id());
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Polygon */
|
|
||||||
|
|
||||||
void polygon_start() {
|
|
||||||
m_impl.polygon_start();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TIter>
|
|
||||||
size_t fill_polygon(TIter it, TIter end) {
|
|
||||||
size_t num_points = 0;
|
|
||||||
for (; it != end; ++it, ++num_points) {
|
|
||||||
m_impl.polygon_add_location(m_projection(it->location()));
|
|
||||||
}
|
|
||||||
return num_points;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TIter>
|
|
||||||
size_t fill_polygon_unique(TIter it, TIter end) {
|
|
||||||
size_t num_points = 0;
|
|
||||||
osmium::Location last_location;
|
|
||||||
for (; it != end; ++it) {
|
|
||||||
if (last_location != it->location()) {
|
|
||||||
last_location = it->location();
|
|
||||||
m_impl.polygon_add_location(m_projection(last_location));
|
|
||||||
++num_points;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return num_points;
|
|
||||||
}
|
|
||||||
|
|
||||||
polygon_type polygon_finish(size_t num_points) {
|
|
||||||
return m_impl.polygon_finish(num_points);
|
|
||||||
}
|
|
||||||
|
|
||||||
polygon_type create_polygon(const osmium::WayNodeList& wnl, use_nodes un = use_nodes::unique, direction dir = direction::forward) {
|
|
||||||
polygon_start();
|
|
||||||
size_t num_points = 0;
|
|
||||||
|
|
||||||
if (un == use_nodes::unique) {
|
|
||||||
osmium::Location last_location;
|
|
||||||
switch (dir) {
|
|
||||||
case direction::forward:
|
|
||||||
num_points = fill_polygon_unique(wnl.cbegin(), wnl.cend());
|
|
||||||
break;
|
|
||||||
case direction::backward:
|
|
||||||
num_points = fill_polygon_unique(wnl.crbegin(), wnl.crend());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (dir) {
|
|
||||||
case direction::forward:
|
|
||||||
num_points = fill_polygon(wnl.cbegin(), wnl.cend());
|
|
||||||
break;
|
|
||||||
case direction::backward:
|
|
||||||
num_points = fill_polygon(wnl.crbegin(), wnl.crend());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_points < 4) {
|
|
||||||
throw osmium::geometry_error("need at least four points for polygon");
|
|
||||||
}
|
|
||||||
|
|
||||||
return polygon_finish(num_points);
|
|
||||||
}
|
|
||||||
|
|
||||||
polygon_type create_polygon(const osmium::Way& way, use_nodes un=use_nodes::unique, direction dir=direction::forward) {
|
|
||||||
try {
|
|
||||||
return create_polygon(way.nodes(), un, dir);
|
|
||||||
} catch (osmium::geometry_error& e) {
|
|
||||||
e.set_id("way", way.id());
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MultiPolygon */
|
|
||||||
|
|
||||||
multipolygon_type create_multipolygon(const osmium::Area& area) {
|
|
||||||
try {
|
|
||||||
size_t num_polygons = 0;
|
|
||||||
size_t num_rings = 0;
|
|
||||||
m_impl.multipolygon_start();
|
|
||||||
|
|
||||||
for (auto it = area.cbegin(); it != area.cend(); ++it) {
|
|
||||||
const osmium::OuterRing& ring = static_cast<const osmium::OuterRing&>(*it);
|
|
||||||
if (it->type() == osmium::item_type::outer_ring) {
|
|
||||||
if (num_polygons > 0) {
|
|
||||||
m_impl.multipolygon_polygon_finish();
|
|
||||||
}
|
|
||||||
m_impl.multipolygon_polygon_start();
|
|
||||||
m_impl.multipolygon_outer_ring_start();
|
|
||||||
add_points(ring);
|
|
||||||
m_impl.multipolygon_outer_ring_finish();
|
|
||||||
++num_rings;
|
|
||||||
++num_polygons;
|
|
||||||
} else if (it->type() == osmium::item_type::inner_ring) {
|
|
||||||
m_impl.multipolygon_inner_ring_start();
|
|
||||||
add_points(ring);
|
|
||||||
m_impl.multipolygon_inner_ring_finish();
|
|
||||||
++num_rings;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if there are no rings, this area is invalid
|
|
||||||
if (num_rings == 0) {
|
|
||||||
throw osmium::geometry_error("area contains no rings");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_impl.multipolygon_polygon_finish();
|
|
||||||
return m_impl.multipolygon_finish();
|
|
||||||
} catch (osmium::geometry_error& e) {
|
|
||||||
e.set_id("area", area.id());
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class GeometryFactory
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_FACTORY_HPP
|
|
@ -1,160 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_GEOJSON_HPP
|
|
||||||
#define OSMIUM_GEOM_GEOJSON_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <osmium/geom/coordinates.hpp>
|
|
||||||
#include <osmium/geom/factory.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
class GeoJSONFactoryImpl {
|
|
||||||
|
|
||||||
std::string m_str;
|
|
||||||
int m_precision;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef std::string point_type;
|
|
||||||
typedef std::string linestring_type;
|
|
||||||
typedef std::string polygon_type;
|
|
||||||
typedef std::string multipolygon_type;
|
|
||||||
typedef std::string ring_type;
|
|
||||||
|
|
||||||
GeoJSONFactoryImpl(int precision = 7) :
|
|
||||||
m_precision(precision) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Point */
|
|
||||||
|
|
||||||
// { "type": "Point", "coordinates": [100.0, 0.0] }
|
|
||||||
point_type make_point(const osmium::geom::Coordinates& xy) const {
|
|
||||||
std::string str {"{\"type\":\"Point\",\"coordinates\":"};
|
|
||||||
xy.append_to_string(str, '[', ',', ']', m_precision);
|
|
||||||
str += "}";
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LineString */
|
|
||||||
|
|
||||||
// { "type": "LineString", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] }
|
|
||||||
void linestring_start() {
|
|
||||||
m_str = "{\"type\":\"LineString\",\"coordinates\":[";
|
|
||||||
}
|
|
||||||
|
|
||||||
void linestring_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
xy.append_to_string(m_str, '[', ',', ']', m_precision);
|
|
||||||
m_str += ',';
|
|
||||||
}
|
|
||||||
|
|
||||||
linestring_type linestring_finish(size_t /* num_points */) {
|
|
||||||
assert(!m_str.empty());
|
|
||||||
std::string str;
|
|
||||||
|
|
||||||
using std::swap;
|
|
||||||
swap(str, m_str);
|
|
||||||
|
|
||||||
str.back() = ']';
|
|
||||||
str += "}";
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MultiPolygon */
|
|
||||||
|
|
||||||
void multipolygon_start() {
|
|
||||||
m_str = "{\"type\":\"MultiPolygon\",\"coordinates\":[";
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_polygon_start() {
|
|
||||||
m_str += '[';
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_polygon_finish() {
|
|
||||||
m_str += "],";
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_outer_ring_start() {
|
|
||||||
m_str += '[';
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_outer_ring_finish() {
|
|
||||||
assert(!m_str.empty());
|
|
||||||
m_str.back() = ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_inner_ring_start() {
|
|
||||||
m_str += ",[";
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_inner_ring_finish() {
|
|
||||||
assert(!m_str.empty());
|
|
||||||
m_str.back() = ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
xy.append_to_string(m_str, '[', ',', ']', m_precision);
|
|
||||||
m_str += ',';
|
|
||||||
}
|
|
||||||
|
|
||||||
multipolygon_type multipolygon_finish() {
|
|
||||||
assert(!m_str.empty());
|
|
||||||
std::string str;
|
|
||||||
|
|
||||||
using std::swap;
|
|
||||||
swap(str, m_str);
|
|
||||||
|
|
||||||
str.back() = ']';
|
|
||||||
str += "}";
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class GeoJSONFactoryImpl
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <typename TProjection = IdentityProjection>
|
|
||||||
using GeoJSONFactory = GeometryFactory<osmium::geom::detail::GeoJSONFactoryImpl, TProjection>;
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_GEOJSON_HPP
|
|
240
third_party/libosmium/include/osmium/geom/geos.hpp
vendored
240
third_party/libosmium/include/osmium/geom/geos.hpp
vendored
@ -1,240 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_GEOS_HPP
|
|
||||||
#define OSMIUM_GEOM_GEOS_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* This file contains code for conversion of OSM geometries into GDAL
|
|
||||||
* geometries.
|
|
||||||
*
|
|
||||||
* @attention If you include this file, you'll need to link with `libgeos`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <geos/geom/Coordinate.h>
|
|
||||||
#include <geos/geom/CoordinateSequence.h>
|
|
||||||
#include <geos/geom/CoordinateSequenceFactory.h>
|
|
||||||
#include <geos/geom/GeometryFactory.h>
|
|
||||||
#include <geos/geom/LinearRing.h>
|
|
||||||
#include <geos/geom/MultiPolygon.h>
|
|
||||||
#include <geos/geom/Point.h>
|
|
||||||
#include <geos/geom/Polygon.h>
|
|
||||||
#include <geos/geom/PrecisionModel.h>
|
|
||||||
#include <geos/util/GEOSException.h>
|
|
||||||
|
|
||||||
#include <osmium/geom/factory.hpp>
|
|
||||||
#include <osmium/geom/coordinates.hpp>
|
|
||||||
|
|
||||||
// MSVC doesn't support throw_with_nested yet
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
# define THROW throw
|
|
||||||
#else
|
|
||||||
# define THROW std::throw_with_nested
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
struct geos_geometry_error : public geometry_error {
|
|
||||||
|
|
||||||
geos_geometry_error(const char* message) :
|
|
||||||
geometry_error(std::string("geometry creation failed in GEOS library: ") + message) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct geos_geometry_error
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
class GEOSFactoryImpl {
|
|
||||||
|
|
||||||
std::unique_ptr<const geos::geom::PrecisionModel> m_precision_model;
|
|
||||||
std::unique_ptr<geos::geom::GeometryFactory> m_our_geos_factory;
|
|
||||||
geos::geom::GeometryFactory* m_geos_factory;
|
|
||||||
|
|
||||||
std::unique_ptr<geos::geom::CoordinateSequence> m_coordinate_sequence;
|
|
||||||
std::vector<std::unique_ptr<geos::geom::LinearRing>> m_rings;
|
|
||||||
std::vector<std::unique_ptr<geos::geom::Polygon>> m_polygons;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef std::unique_ptr<geos::geom::Point> point_type;
|
|
||||||
typedef std::unique_ptr<geos::geom::LineString> linestring_type;
|
|
||||||
typedef std::unique_ptr<geos::geom::Polygon> polygon_type;
|
|
||||||
typedef std::unique_ptr<geos::geom::MultiPolygon> multipolygon_type;
|
|
||||||
typedef std::unique_ptr<geos::geom::LinearRing> ring_type;
|
|
||||||
|
|
||||||
explicit GEOSFactoryImpl(geos::geom::GeometryFactory& geos_factory) :
|
|
||||||
m_precision_model(nullptr),
|
|
||||||
m_our_geos_factory(nullptr),
|
|
||||||
m_geos_factory(&geos_factory) {
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit GEOSFactoryImpl(int srid = -1) :
|
|
||||||
m_precision_model(new geos::geom::PrecisionModel),
|
|
||||||
m_our_geos_factory(new geos::geom::GeometryFactory(m_precision_model.get(), srid)),
|
|
||||||
m_geos_factory(m_our_geos_factory.get()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Point */
|
|
||||||
|
|
||||||
point_type make_point(const osmium::geom::Coordinates& xy) const {
|
|
||||||
try {
|
|
||||||
return point_type(m_geos_factory->createPoint(geos::geom::Coordinate(xy.x, xy.y)));
|
|
||||||
} catch (geos::util::GEOSException& e) {
|
|
||||||
THROW(osmium::geos_geometry_error(e.what()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LineString */
|
|
||||||
|
|
||||||
void linestring_start() {
|
|
||||||
try {
|
|
||||||
m_coordinate_sequence.reset(m_geos_factory->getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2));
|
|
||||||
} catch (geos::util::GEOSException& e) {
|
|
||||||
THROW(osmium::geos_geometry_error(e.what()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void linestring_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
try {
|
|
||||||
m_coordinate_sequence->add(geos::geom::Coordinate(xy.x, xy.y));
|
|
||||||
} catch (geos::util::GEOSException& e) {
|
|
||||||
THROW(osmium::geos_geometry_error(e.what()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
linestring_type linestring_finish(size_t /* num_points */) {
|
|
||||||
try {
|
|
||||||
return linestring_type(m_geos_factory->createLineString(m_coordinate_sequence.release()));
|
|
||||||
} catch (geos::util::GEOSException& e) {
|
|
||||||
THROW(osmium::geos_geometry_error(e.what()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MultiPolygon */
|
|
||||||
|
|
||||||
void multipolygon_start() {
|
|
||||||
m_polygons.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_polygon_start() {
|
|
||||||
m_rings.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_polygon_finish() {
|
|
||||||
try {
|
|
||||||
assert(!m_rings.empty());
|
|
||||||
auto inner_rings = new std::vector<geos::geom::Geometry*>;
|
|
||||||
std::transform(std::next(m_rings.begin(), 1), m_rings.end(), std::back_inserter(*inner_rings), [](std::unique_ptr<geos::geom::LinearRing>& r) {
|
|
||||||
return r.release();
|
|
||||||
});
|
|
||||||
m_polygons.emplace_back(m_geos_factory->createPolygon(m_rings[0].release(), inner_rings));
|
|
||||||
m_rings.clear();
|
|
||||||
} catch (geos::util::GEOSException& e) {
|
|
||||||
THROW(osmium::geos_geometry_error(e.what()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_outer_ring_start() {
|
|
||||||
try {
|
|
||||||
m_coordinate_sequence.reset(m_geos_factory->getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2));
|
|
||||||
} catch (geos::util::GEOSException& e) {
|
|
||||||
THROW(osmium::geos_geometry_error(e.what()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_outer_ring_finish() {
|
|
||||||
try {
|
|
||||||
m_rings.emplace_back(m_geos_factory->createLinearRing(m_coordinate_sequence.release()));
|
|
||||||
} catch (geos::util::GEOSException& e) {
|
|
||||||
THROW(osmium::geos_geometry_error(e.what()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_inner_ring_start() {
|
|
||||||
try {
|
|
||||||
m_coordinate_sequence.reset(m_geos_factory->getCoordinateSequenceFactory()->create(static_cast<size_t>(0), 2));
|
|
||||||
} catch (geos::util::GEOSException& e) {
|
|
||||||
THROW(osmium::geos_geometry_error(e.what()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_inner_ring_finish() {
|
|
||||||
try {
|
|
||||||
m_rings.emplace_back(m_geos_factory->createLinearRing(m_coordinate_sequence.release()));
|
|
||||||
} catch (geos::util::GEOSException& e) {
|
|
||||||
THROW(osmium::geos_geometry_error(e.what()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
try {
|
|
||||||
m_coordinate_sequence->add(geos::geom::Coordinate(xy.x, xy.y));
|
|
||||||
} catch (geos::util::GEOSException& e) {
|
|
||||||
THROW(osmium::geos_geometry_error(e.what()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
multipolygon_type multipolygon_finish() {
|
|
||||||
try {
|
|
||||||
auto polygons = new std::vector<geos::geom::Geometry*>;
|
|
||||||
std::transform(m_polygons.begin(), m_polygons.end(), std::back_inserter(*polygons), [](std::unique_ptr<geos::geom::Polygon>& p) {
|
|
||||||
return p.release();
|
|
||||||
});
|
|
||||||
m_polygons.clear();
|
|
||||||
return multipolygon_type(m_geos_factory->createMultiPolygon(polygons));
|
|
||||||
} catch (geos::util::GEOSException& e) {
|
|
||||||
THROW(osmium::geos_geometry_error(e.what()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class GEOSFactoryImpl
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <typename TProjection = IdentityProjection>
|
|
||||||
using GEOSFactory = GeometryFactory<osmium::geom::detail::GEOSFactoryImpl, TProjection>;
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#undef THROW
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_GEOS_HPP
|
|
@ -1,94 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_HAVERSINE_HPP
|
|
||||||
#define OSMIUM_GEOM_HAVERSINE_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <iterator>
|
|
||||||
|
|
||||||
#include <osmium/geom/coordinates.hpp>
|
|
||||||
#include <osmium/geom/util.hpp>
|
|
||||||
#include <osmium/osm/node_ref.hpp>
|
|
||||||
#include <osmium/osm/way.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Functions to calculate arc distance on Earth using the haversine formula.
|
|
||||||
*
|
|
||||||
* See http://en.wikipedia.org/wiki/Haversine_formula
|
|
||||||
*
|
|
||||||
* Implementation derived from
|
|
||||||
* http://blog.julien.cayzac.name/2008/10/arc-and-distance-between-two-points-on.html
|
|
||||||
*/
|
|
||||||
namespace haversine {
|
|
||||||
|
|
||||||
/// @brief Earth's quadratic mean radius for WGS84
|
|
||||||
constexpr double EARTH_RADIUS_IN_METERS = 6372797.560856;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate distance in meters between two sets of coordinates.
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
lonh *= lonh;
|
|
||||||
double lath = 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate length of way.
|
|
||||||
*/
|
|
||||||
inline double distance(const osmium::WayNodeList& wnl) {
|
|
||||||
double sum_length = 0;
|
|
||||||
|
|
||||||
for (auto it = wnl.begin(); it != wnl.end(); ++it) {
|
|
||||||
if (std::next(it) != wnl.end()) {
|
|
||||||
sum_length += distance(it->location(), std::next(it)->location());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace haversine
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_HAVERSINE_HPP
|
|
@ -1,110 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_MERCATOR_PROJECTION_HPP
|
|
||||||
#define OSMIUM_GEOM_MERCATOR_PROJECTION_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <osmium/geom/coordinates.hpp>
|
|
||||||
#include <osmium/geom/util.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
constexpr double earth_radius_for_epsg3857 = 6378137.0;
|
|
||||||
constexpr double max_coordinate_epsg3857 = 20037508.34;
|
|
||||||
|
|
||||||
constexpr inline double lon_to_x(double lon) {
|
|
||||||
return earth_radius_for_epsg3857 * deg_to_rad(lon);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double lat_to_y(double lat) { // not constexpr because math functions aren't
|
|
||||||
return earth_radius_for_epsg3857 * std::log(std::tan(osmium::geom::PI/4 + deg_to_rad(lat)/2));
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline double x_to_lon(double x) {
|
|
||||||
return rad_to_deg(x) / earth_radius_for_epsg3857;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double y_to_lat(double y) { // not constexpr because math functions aren't
|
|
||||||
return rad_to_deg(2 * std::atan(std::exp(y / earth_radius_for_epsg3857)) - osmium::geom::PI/2);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum latitude that can be projected with the Web Mercator
|
|
||||||
* (EPSG:3857) projection.
|
|
||||||
*/
|
|
||||||
constexpr double MERCATOR_MAX_LAT = 85.0511288;
|
|
||||||
|
|
||||||
inline Coordinates lonlat_to_mercator(const Coordinates& c) {
|
|
||||||
return Coordinates(detail::lon_to_x(c.x), detail::lat_to_y(c.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Coordinates mercator_to_lonlat(const Coordinates& c) {
|
|
||||||
return Coordinates(detail::x_to_lon(c.x), detail::y_to_lat(c.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functor that does projection from WGS84 (EPSG:4326) to "Web
|
|
||||||
* Mercator" (EPSG:3857)
|
|
||||||
*/
|
|
||||||
class MercatorProjection {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Coordinates operator()(osmium::Location location) const {
|
|
||||||
return Coordinates {detail::lon_to_x(location.lon()), detail::lat_to_y(location.lat())};
|
|
||||||
}
|
|
||||||
|
|
||||||
int epsg() const noexcept {
|
|
||||||
return 3857;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string proj_string() const {
|
|
||||||
return "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs";
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class MercatorProjection
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_MERCATOR_PROJECTION_HPP
|
|
178
third_party/libosmium/include/osmium/geom/ogr.hpp
vendored
178
third_party/libosmium/include/osmium/geom/ogr.hpp
vendored
@ -1,178 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_OGR_HPP
|
|
||||||
#define OSMIUM_GEOM_OGR_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* This file contains code for conversion of OSM geometries into OGR
|
|
||||||
* geometries.
|
|
||||||
*
|
|
||||||
* @attention If you include this file, you'll need to link with `libgdal`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <ogr_geometry.h>
|
|
||||||
|
|
||||||
#include <osmium/geom/coordinates.hpp>
|
|
||||||
#include <osmium/geom/factory.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
class OGRFactoryImpl {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef std::unique_ptr<OGRPoint> point_type;
|
|
||||||
typedef std::unique_ptr<OGRLineString> linestring_type;
|
|
||||||
typedef std::unique_ptr<OGRPolygon> polygon_type;
|
|
||||||
typedef std::unique_ptr<OGRMultiPolygon> multipolygon_type;
|
|
||||||
typedef std::unique_ptr<OGRLinearRing> ring_type;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
linestring_type m_linestring;
|
|
||||||
multipolygon_type m_multipolygon;
|
|
||||||
polygon_type m_polygon;
|
|
||||||
ring_type m_ring;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
OGRFactoryImpl() = default;
|
|
||||||
|
|
||||||
/* Point */
|
|
||||||
|
|
||||||
point_type make_point(const osmium::geom::Coordinates& xy) const {
|
|
||||||
return point_type(new OGRPoint(xy.x, xy.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LineString */
|
|
||||||
|
|
||||||
void linestring_start() {
|
|
||||||
m_linestring = std::unique_ptr<OGRLineString>(new OGRLineString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void linestring_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
assert(!!m_linestring);
|
|
||||||
m_linestring->addPoint(xy.x, xy.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
linestring_type linestring_finish(size_t /* num_points */) {
|
|
||||||
return std::move(m_linestring);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Polygon */
|
|
||||||
|
|
||||||
void polygon_start() {
|
|
||||||
m_ring = std::unique_ptr<OGRLinearRing>(new OGRLinearRing());
|
|
||||||
}
|
|
||||||
|
|
||||||
void polygon_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
assert(!!m_ring);
|
|
||||||
m_ring->addPoint(xy.x, xy.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
polygon_type polygon_finish(size_t /* num_points */) {
|
|
||||||
std::unique_ptr<OGRPolygon> polygon = std::unique_ptr<OGRPolygon>(new OGRPolygon());
|
|
||||||
polygon->addRingDirectly(m_ring.release());
|
|
||||||
return polygon;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MultiPolygon */
|
|
||||||
|
|
||||||
void multipolygon_start() {
|
|
||||||
m_multipolygon.reset(new OGRMultiPolygon());
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_polygon_start() {
|
|
||||||
m_polygon.reset(new OGRPolygon());
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_polygon_finish() {
|
|
||||||
assert(!!m_multipolygon);
|
|
||||||
assert(!!m_polygon);
|
|
||||||
m_multipolygon->addGeometryDirectly(m_polygon.release());
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_outer_ring_start() {
|
|
||||||
m_ring.reset(new OGRLinearRing());
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_outer_ring_finish() {
|
|
||||||
assert(!!m_polygon);
|
|
||||||
assert(!!m_ring);
|
|
||||||
m_polygon->addRingDirectly(m_ring.release());
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_inner_ring_start() {
|
|
||||||
m_ring.reset(new OGRLinearRing());
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_inner_ring_finish() {
|
|
||||||
assert(!!m_polygon);
|
|
||||||
assert(!!m_ring);
|
|
||||||
m_polygon->addRingDirectly(m_ring.release());
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
assert(!!m_polygon);
|
|
||||||
assert(!!m_ring);
|
|
||||||
m_ring->addPoint(xy.x, xy.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
multipolygon_type multipolygon_finish() {
|
|
||||||
assert(!!m_multipolygon);
|
|
||||||
return std::move(m_multipolygon);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class OGRFactoryImpl
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <typename TProjection = IdentityProjection>
|
|
||||||
using OGRFactory = GeometryFactory<osmium::geom::detail::OGRFactoryImpl, TProjection>;
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_OGR_HPP
|
|
@ -1,170 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_PROJECTION_HPP
|
|
||||||
#define OSMIUM_GEOM_PROJECTION_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* This file contains code for projecting OSM locations to arbitrary
|
|
||||||
* coordinate reference systems. It is based on the Proj.4 library.
|
|
||||||
*
|
|
||||||
* @attention If you include this file, you'll need to link with `libproj`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <proj_api.h>
|
|
||||||
|
|
||||||
#include <osmium/geom/coordinates.hpp>
|
|
||||||
#include <osmium/geom/util.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* C++ wrapper for a Coordinate Reference System of the proj library.
|
|
||||||
*/
|
|
||||||
class CRS {
|
|
||||||
|
|
||||||
struct ProjCRSDeleter {
|
|
||||||
void operator()(void* crs) {
|
|
||||||
pj_free(crs);
|
|
||||||
}
|
|
||||||
}; // struct ProjCRSDeleter
|
|
||||||
|
|
||||||
std::unique_ptr<void, ProjCRSDeleter> m_crs;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
CRS(const std::string& crs) :
|
|
||||||
m_crs(pj_init_plus(crs.c_str()), ProjCRSDeleter()) {
|
|
||||||
if (!m_crs) {
|
|
||||||
throw osmium::projection_error(std::string("creation of CRS failed: ") + pj_strerrno(*pj_get_errno_ref()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CRS(int epsg) :
|
|
||||||
CRS(std::string("+init=epsg:") + std::to_string(epsg)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get underlying projPJ handle from proj library.
|
|
||||||
*/
|
|
||||||
projPJ get() const {
|
|
||||||
return m_crs.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_latlong() const {
|
|
||||||
return pj_is_latlong(m_crs.get()) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_geocent() const {
|
|
||||||
return pj_is_geocent(m_crs.get()) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class CRS
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform coordinates from one CRS into another. Wraps the same
|
|
||||||
* function of the proj library.
|
|
||||||
*
|
|
||||||
* Coordinates have to be in radians and are produced in radians.
|
|
||||||
*
|
|
||||||
* @throws osmmium::projection_error if the projection fails
|
|
||||||
*/
|
|
||||||
inline Coordinates transform(const CRS& src, const CRS& dest, Coordinates c) {
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functor that does projection from WGS84 (EPSG:4326) to the given
|
|
||||||
* CRS.
|
|
||||||
*/
|
|
||||||
class Projection {
|
|
||||||
|
|
||||||
int m_epsg;
|
|
||||||
std::string m_proj_string;
|
|
||||||
CRS m_crs_wgs84 {4326};
|
|
||||||
CRS m_crs_user;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Projection(const std::string& proj_string) :
|
|
||||||
m_epsg(-1),
|
|
||||||
m_proj_string(proj_string),
|
|
||||||
m_crs_user(proj_string) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Projection(int epsg) :
|
|
||||||
m_epsg(epsg),
|
|
||||||
m_proj_string(std::string("+init=epsg:") + std::to_string(epsg)),
|
|
||||||
m_crs_user(epsg) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Coordinates operator()(osmium::Location location) const {
|
|
||||||
Coordinates c {location.lon(), location.lat()};
|
|
||||||
|
|
||||||
if (m_epsg != 4326) {
|
|
||||||
c = transform(m_crs_wgs84, m_crs_user, Coordinates(deg_to_rad(location.lon()), deg_to_rad(location.lat())));
|
|
||||||
if (m_crs_user.is_latlong()) {
|
|
||||||
c.x = rad_to_deg(c.x);
|
|
||||||
c.y = rad_to_deg(c.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
int epsg() const noexcept {
|
|
||||||
return m_epsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string proj_string() const {
|
|
||||||
return m_proj_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class Projection
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_PROJECTION_HPP
|
|
@ -1,190 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_RAPID_GEOJSON_HPP
|
|
||||||
#define OSMIUM_GEOM_RAPID_GEOJSON_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <osmium/geom/coordinates.hpp>
|
|
||||||
#include <osmium/geom/factory.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A geometry factory implementation that can be used with the
|
|
||||||
* RapidJSON (https://github.com/miloyip/rapidjson) JSON writer.
|
|
||||||
*/
|
|
||||||
template <typename TWriter>
|
|
||||||
class RapidGeoJSONFactoryImpl {
|
|
||||||
|
|
||||||
TWriter* m_writer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef void point_type;
|
|
||||||
typedef void linestring_type;
|
|
||||||
typedef void polygon_type;
|
|
||||||
typedef void multipolygon_type;
|
|
||||||
typedef void ring_type;
|
|
||||||
|
|
||||||
RapidGeoJSONFactoryImpl(TWriter& writer) :
|
|
||||||
m_writer(&writer) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Point */
|
|
||||||
|
|
||||||
// { "type": "Point", "coordinates": [100.0, 0.0] }
|
|
||||||
point_type make_point(const osmium::geom::Coordinates& xy) const {
|
|
||||||
m_writer->String("geometry");
|
|
||||||
m_writer->StartObject();
|
|
||||||
m_writer->String("type");
|
|
||||||
m_writer->String("Point");
|
|
||||||
m_writer->String("coordinates");
|
|
||||||
m_writer->StartArray();
|
|
||||||
m_writer->Double(xy.x);
|
|
||||||
m_writer->Double(xy.y);
|
|
||||||
m_writer->EndArray();
|
|
||||||
m_writer->EndObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LineString */
|
|
||||||
|
|
||||||
// { "type": "LineString", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] }
|
|
||||||
void linestring_start() {
|
|
||||||
m_writer->String("geometry");
|
|
||||||
m_writer->StartObject();
|
|
||||||
m_writer->String("type");
|
|
||||||
m_writer->String("LineString");
|
|
||||||
m_writer->String("coordinates");
|
|
||||||
m_writer->StartArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
void linestring_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
m_writer->StartArray();
|
|
||||||
m_writer->Double(xy.x);
|
|
||||||
m_writer->Double(xy.y);
|
|
||||||
m_writer->EndArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
linestring_type linestring_finish(size_t /* num_points */) {
|
|
||||||
m_writer->EndArray();
|
|
||||||
m_writer->EndObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Polygon */
|
|
||||||
|
|
||||||
// { "type": "Polygon", "coordinates": [[[100.0, 0.0], [101.0, 1.0]]] }
|
|
||||||
void polygon_start() {
|
|
||||||
m_writer->String("geometry");
|
|
||||||
m_writer->StartObject();
|
|
||||||
m_writer->String("type");
|
|
||||||
m_writer->String("Polygon");
|
|
||||||
m_writer->String("coordinates");
|
|
||||||
m_writer->StartArray();
|
|
||||||
m_writer->StartArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
void polygon_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
m_writer->StartArray();
|
|
||||||
m_writer->Double(xy.x);
|
|
||||||
m_writer->Double(xy.y);
|
|
||||||
m_writer->EndArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
polygon_type polygon_finish(size_t /* num_points */) {
|
|
||||||
m_writer->EndArray();
|
|
||||||
m_writer->EndArray();
|
|
||||||
m_writer->EndObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MultiPolygon */
|
|
||||||
|
|
||||||
void multipolygon_start() {
|
|
||||||
m_writer->String("geometry");
|
|
||||||
m_writer->StartObject();
|
|
||||||
m_writer->String("type");
|
|
||||||
m_writer->String("MultiPolygon");
|
|
||||||
m_writer->String("coordinates");
|
|
||||||
m_writer->StartArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_polygon_start() {
|
|
||||||
m_writer->StartArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_polygon_finish() {
|
|
||||||
m_writer->EndArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_outer_ring_start() {
|
|
||||||
m_writer->StartArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_outer_ring_finish() {
|
|
||||||
m_writer->EndArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_inner_ring_start() {
|
|
||||||
m_writer->StartArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_inner_ring_finish() {
|
|
||||||
m_writer->EndArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
m_writer->StartArray();
|
|
||||||
m_writer->Double(xy.x);
|
|
||||||
m_writer->Double(xy.y);
|
|
||||||
m_writer->EndArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
multipolygon_type multipolygon_finish() {
|
|
||||||
m_writer->EndArray();
|
|
||||||
m_writer->EndObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class RapidGeoJSONFactoryImpl
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <typename TWriter, typename TProjection = IdentityProjection>
|
|
||||||
using RapidGeoJSONFactory = GeometryFactory<detail::RapidGeoJSONFactoryImpl<TWriter>, TProjection>;
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_RAPID_GEOJSON_HPP
|
|
@ -1,57 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_RELATIONS_HPP
|
|
||||||
#define OSMIUM_GEOM_RELATIONS_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <osmium/osm/box.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether one geometry contains another.
|
|
||||||
*/
|
|
||||||
inline bool contains(const osmium::Box& a, const osmium::Box& b) {
|
|
||||||
return ((a.bottom_left().x() >= b.bottom_left().x()) &&
|
|
||||||
(a.top_right().x() <= b.top_right().x()) &&
|
|
||||||
(a.bottom_left().y() >= b.bottom_left().y()) &&
|
|
||||||
(a.top_right().y() <= b.top_right().y()));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_RELATIONS_HPP
|
|
101
third_party/libosmium/include/osmium/geom/tile.hpp
vendored
101
third_party/libosmium/include/osmium/geom/tile.hpp
vendored
@ -1,101 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_TILE_HPP
|
|
||||||
#define OSMIUM_GEOM_TILE_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include <osmium/geom/mercator_projection.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T restrict_to_range(T value, T min, T max) {
|
|
||||||
if (value < min) return min;
|
|
||||||
if (value > max) return max;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A tile in the usual Mercator projection.
|
|
||||||
*/
|
|
||||||
struct Tile {
|
|
||||||
|
|
||||||
uint32_t x;
|
|
||||||
uint32_t y;
|
|
||||||
uint32_t z;
|
|
||||||
|
|
||||||
explicit Tile(uint32_t zoom, uint32_t tx, uint32_t ty) noexcept : x(tx), y(ty), z(zoom) {
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit Tile(uint32_t zoom, const osmium::Location& location) :
|
|
||||||
z(zoom) {
|
|
||||||
osmium::geom::Coordinates c = lonlat_to_mercator(location);
|
|
||||||
const int32_t n = 1 << zoom;
|
|
||||||
const double scale = detail::max_coordinate_epsg3857 * 2 / n;
|
|
||||||
x = uint32_t(detail::restrict_to_range<int32_t>(int32_t((c.x + detail::max_coordinate_epsg3857) / scale), 0, n-1));
|
|
||||||
y = uint32_t(detail::restrict_to_range<int32_t>(int32_t((detail::max_coordinate_epsg3857 - c.y) / scale), 0, n-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct Tile
|
|
||||||
|
|
||||||
inline bool operator==(const Tile& a, const Tile& b) {
|
|
||||||
return a.z == b.z && a.x == b.x && a.y == b.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const Tile& a, const Tile& b) {
|
|
||||||
return ! (a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This defines an arbitrary order on tiles for use in std::map etc.
|
|
||||||
*/
|
|
||||||
inline bool operator<(const Tile& a, const Tile& b) {
|
|
||||||
if (a.z < b.z) return true;
|
|
||||||
if (a.z > b.z) return false;
|
|
||||||
if (a.x < b.x) return true;
|
|
||||||
if (a.x > b.x) return false;
|
|
||||||
return a.y < b.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_TILE_HPP
|
|
@ -1,75 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_UTIL_HPP
|
|
||||||
#define OSMIUM_GEOM_UTIL_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception thrown when a projection object can not be initialized or the
|
|
||||||
* projection of some coordinates can not be calculated.
|
|
||||||
*/
|
|
||||||
struct projection_error : public std::runtime_error {
|
|
||||||
|
|
||||||
projection_error(const std::string& what) :
|
|
||||||
std::runtime_error(what) {
|
|
||||||
}
|
|
||||||
|
|
||||||
projection_error(const char* what) :
|
|
||||||
std::runtime_error(what) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct projection_error
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
constexpr double PI = 3.14159265358979323846;
|
|
||||||
|
|
||||||
/// Convert angle from degrees to radians.
|
|
||||||
inline constexpr double deg_to_rad(double degree) noexcept {
|
|
||||||
return degree * (PI / 180.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert angle from radians to degrees.
|
|
||||||
inline constexpr double rad_to_deg(double radians) noexcept {
|
|
||||||
return radians * (180.0 / PI);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_UTIL_HPP
|
|
273
third_party/libosmium/include/osmium/geom/wkb.hpp
vendored
273
third_party/libosmium/include/osmium/geom/wkb.hpp
vendored
@ -1,273 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_WKB_HPP
|
|
||||||
#define OSMIUM_GEOM_WKB_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <osmium/geom/coordinates.hpp>
|
|
||||||
#include <osmium/geom/factory.hpp>
|
|
||||||
#include <osmium/util/cast.hpp>
|
|
||||||
#include <osmium/util/endian.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
enum class wkb_type : bool {
|
|
||||||
wkb = false,
|
|
||||||
ewkb = true
|
|
||||||
}; // enum class wkb_type
|
|
||||||
|
|
||||||
enum class out_type : bool {
|
|
||||||
binary = false,
|
|
||||||
hex = true
|
|
||||||
}; // enum class out_type
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void str_push(std::string& str, T data) {
|
|
||||||
size_t size = str.size();
|
|
||||||
str.resize(size + sizeof(T));
|
|
||||||
std::copy_n(reinterpret_cast<char*>(&data), sizeof(T), &str[size]);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string convert_to_hex(const std::string& str) {
|
|
||||||
static const char* lookup_hex = "0123456789ABCDEF";
|
|
||||||
std::string out;
|
|
||||||
|
|
||||||
for (char c : str) {
|
|
||||||
out += lookup_hex[(c >> 4) & 0xf];
|
|
||||||
out += lookup_hex[c & 0xf];
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
class WKBFactoryImpl {
|
|
||||||
|
|
||||||
/// OSM data always uses SRID 4326 (WGS84).
|
|
||||||
static constexpr uint32_t srid = 4326;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type of WKB geometry.
|
|
||||||
* These definitions are from
|
|
||||||
* 99-049_OpenGIS_Simple_Features_Specification_For_SQL_Rev_1.1.pdf (for WKB)
|
|
||||||
* and http://trac.osgeo.org/postgis/browser/trunk/doc/ZMSgeoms.txt (for EWKB).
|
|
||||||
* They are used to encode geometries into the WKB format.
|
|
||||||
*/
|
|
||||||
enum wkbGeometryType : uint32_t {
|
|
||||||
wkbPoint = 1,
|
|
||||||
wkbLineString = 2,
|
|
||||||
wkbPolygon = 3,
|
|
||||||
wkbMultiPoint = 4,
|
|
||||||
wkbMultiLineString = 5,
|
|
||||||
wkbMultiPolygon = 6,
|
|
||||||
wkbGeometryCollection = 7,
|
|
||||||
|
|
||||||
// SRID-presence flag (EWKB)
|
|
||||||
wkbSRID = 0x20000000
|
|
||||||
}; // enum wkbGeometryType
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Byte order marker in WKB geometry.
|
|
||||||
*/
|
|
||||||
enum class wkb_byte_order_type : uint8_t {
|
|
||||||
XDR = 0, // Big Endian
|
|
||||||
NDR = 1 // Little Endian
|
|
||||||
}; // enum class wkb_byte_order_type
|
|
||||||
|
|
||||||
std::string m_data;
|
|
||||||
uint32_t m_points {0};
|
|
||||||
wkb_type m_wkb_type;
|
|
||||||
out_type m_out_type;
|
|
||||||
|
|
||||||
size_t m_linestring_size_offset = 0;
|
|
||||||
size_t m_polygons = 0;
|
|
||||||
size_t m_rings = 0;
|
|
||||||
size_t m_multipolygon_size_offset = 0;
|
|
||||||
size_t m_polygon_size_offset = 0;
|
|
||||||
size_t m_ring_size_offset = 0;
|
|
||||||
|
|
||||||
size_t header(std::string& str, wkbGeometryType type, bool add_length) const {
|
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
||||||
str_push(str, wkb_byte_order_type::NDR);
|
|
||||||
#else
|
|
||||||
str_push(str, wkb_byte_order_type::XDR);
|
|
||||||
#endif
|
|
||||||
if (m_wkb_type == wkb_type::ewkb) {
|
|
||||||
str_push(str, type | wkbSRID);
|
|
||||||
str_push(str, srid);
|
|
||||||
} else {
|
|
||||||
str_push(str, type);
|
|
||||||
}
|
|
||||||
size_t offset = str.size();
|
|
||||||
if (add_length) {
|
|
||||||
str_push(str, static_cast<uint32_t>(0));
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_size(const size_t offset, const size_t size) {
|
|
||||||
*reinterpret_cast<uint32_t*>(&m_data[offset]) = static_cast_with_assert<uint32_t>(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef std::string point_type;
|
|
||||||
typedef std::string linestring_type;
|
|
||||||
typedef std::string polygon_type;
|
|
||||||
typedef std::string multipolygon_type;
|
|
||||||
typedef std::string ring_type;
|
|
||||||
|
|
||||||
explicit WKBFactoryImpl(wkb_type wtype = wkb_type::wkb, out_type otype = out_type::binary) :
|
|
||||||
m_wkb_type(wtype),
|
|
||||||
m_out_type(otype) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Point */
|
|
||||||
|
|
||||||
point_type make_point(const osmium::geom::Coordinates& xy) const {
|
|
||||||
std::string data;
|
|
||||||
header(data, wkbPoint, false);
|
|
||||||
str_push(data, xy.x);
|
|
||||||
str_push(data, xy.y);
|
|
||||||
|
|
||||||
if (m_out_type == out_type::hex) {
|
|
||||||
return convert_to_hex(data);
|
|
||||||
} else {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LineString */
|
|
||||||
|
|
||||||
void linestring_start() {
|
|
||||||
m_data.clear();
|
|
||||||
m_linestring_size_offset = header(m_data, wkbLineString, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void linestring_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
str_push(m_data, xy.x);
|
|
||||||
str_push(m_data, xy.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
linestring_type linestring_finish(size_t num_points) {
|
|
||||||
set_size(m_linestring_size_offset, num_points);
|
|
||||||
std::string data;
|
|
||||||
|
|
||||||
using std::swap;
|
|
||||||
swap(data, m_data);
|
|
||||||
|
|
||||||
if (m_out_type == out_type::hex) {
|
|
||||||
return convert_to_hex(data);
|
|
||||||
} else {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MultiPolygon */
|
|
||||||
|
|
||||||
void multipolygon_start() {
|
|
||||||
m_data.clear();
|
|
||||||
m_polygons = 0;
|
|
||||||
m_multipolygon_size_offset = header(m_data, wkbMultiPolygon, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_polygon_start() {
|
|
||||||
++m_polygons;
|
|
||||||
m_rings = 0;
|
|
||||||
m_polygon_size_offset = header(m_data, wkbPolygon, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_polygon_finish() {
|
|
||||||
set_size(m_polygon_size_offset, m_rings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_outer_ring_start() {
|
|
||||||
++m_rings;
|
|
||||||
m_points = 0;
|
|
||||||
m_ring_size_offset = m_data.size();
|
|
||||||
str_push(m_data, static_cast<uint32_t>(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_outer_ring_finish() {
|
|
||||||
set_size(m_ring_size_offset, m_points);
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_inner_ring_start() {
|
|
||||||
++m_rings;
|
|
||||||
m_points = 0;
|
|
||||||
m_ring_size_offset = m_data.size();
|
|
||||||
str_push(m_data, static_cast<uint32_t>(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_inner_ring_finish() {
|
|
||||||
set_size(m_ring_size_offset, m_points);
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
str_push(m_data, xy.x);
|
|
||||||
str_push(m_data, xy.y);
|
|
||||||
++m_points;
|
|
||||||
}
|
|
||||||
|
|
||||||
multipolygon_type multipolygon_finish() {
|
|
||||||
set_size(m_multipolygon_size_offset, m_polygons);
|
|
||||||
std::string data;
|
|
||||||
|
|
||||||
using std::swap;
|
|
||||||
swap(data, m_data);
|
|
||||||
|
|
||||||
if (m_out_type == out_type::hex) {
|
|
||||||
return convert_to_hex(data);
|
|
||||||
} else {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class WKBFactoryImpl
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <typename TProjection = IdentityProjection>
|
|
||||||
using WKBFactory = GeometryFactory<osmium::geom::detail::WKBFactoryImpl, TProjection>;
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_WKB_HPP
|
|
156
third_party/libosmium/include/osmium/geom/wkt.hpp
vendored
156
third_party/libosmium/include/osmium/geom/wkt.hpp
vendored
@ -1,156 +0,0 @@
|
|||||||
#ifndef OSMIUM_GEOM_WKT_HPP
|
|
||||||
#define OSMIUM_GEOM_WKT_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <osmium/geom/coordinates.hpp>
|
|
||||||
#include <osmium/geom/factory.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace geom {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
class WKTFactoryImpl {
|
|
||||||
|
|
||||||
std::string m_str;
|
|
||||||
int m_precision;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef std::string point_type;
|
|
||||||
typedef std::string linestring_type;
|
|
||||||
typedef std::string polygon_type;
|
|
||||||
typedef std::string multipolygon_type;
|
|
||||||
typedef std::string ring_type;
|
|
||||||
|
|
||||||
WKTFactoryImpl(int precision = 7) :
|
|
||||||
m_precision(precision) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Point */
|
|
||||||
|
|
||||||
point_type make_point(const osmium::geom::Coordinates& xy) const {
|
|
||||||
std::string str {"POINT"};
|
|
||||||
xy.append_to_string(str, '(', ' ', ')', m_precision);
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LineString */
|
|
||||||
|
|
||||||
void linestring_start() {
|
|
||||||
m_str = "LINESTRING(";
|
|
||||||
}
|
|
||||||
|
|
||||||
void linestring_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
xy.append_to_string(m_str, ' ', m_precision);
|
|
||||||
m_str += ',';
|
|
||||||
}
|
|
||||||
|
|
||||||
linestring_type linestring_finish(size_t /* num_points */) {
|
|
||||||
assert(!m_str.empty());
|
|
||||||
std::string str;
|
|
||||||
|
|
||||||
using std::swap;
|
|
||||||
swap(str, m_str);
|
|
||||||
|
|
||||||
str.back() = ')';
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MultiPolygon */
|
|
||||||
|
|
||||||
void multipolygon_start() {
|
|
||||||
m_str = "MULTIPOLYGON(";
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_polygon_start() {
|
|
||||||
m_str += '(';
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_polygon_finish() {
|
|
||||||
m_str += "),";
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_outer_ring_start() {
|
|
||||||
m_str += '(';
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_outer_ring_finish() {
|
|
||||||
assert(!m_str.empty());
|
|
||||||
m_str.back() = ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_inner_ring_start() {
|
|
||||||
m_str += ",(";
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_inner_ring_finish() {
|
|
||||||
assert(!m_str.empty());
|
|
||||||
m_str.back() = ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
void multipolygon_add_location(const osmium::geom::Coordinates& xy) {
|
|
||||||
xy.append_to_string(m_str, ' ', m_precision);
|
|
||||||
m_str += ',';
|
|
||||||
}
|
|
||||||
|
|
||||||
multipolygon_type multipolygon_finish() {
|
|
||||||
assert(!m_str.empty());
|
|
||||||
std::string str;
|
|
||||||
|
|
||||||
using std::swap;
|
|
||||||
swap(str, m_str);
|
|
||||||
|
|
||||||
str.back() = ')';
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class WKTFactoryImpl
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <typename TProjection = IdentityProjection>
|
|
||||||
using WKTFactory = GeometryFactory<osmium::geom::detail::WKTFactoryImpl, TProjection>;
|
|
||||||
|
|
||||||
} // namespace geom
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_GEOM_WKT_HPP
|
|
94
third_party/libosmium/include/osmium/handler.hpp
vendored
94
third_party/libosmium/include/osmium/handler.hpp
vendored
@ -1,94 +0,0 @@
|
|||||||
#ifndef OSMIUM_HANDLER_HPP
|
|
||||||
#define OSMIUM_HANDLER_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <osmium/fwd.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Osmium handlers provide callbacks for OSM objects
|
|
||||||
*/
|
|
||||||
namespace handler {
|
|
||||||
|
|
||||||
class Handler {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void osm_object(const osmium::OSMObject&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void node(const osmium::Node&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void way(const osmium::Way&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation(const osmium::Relation&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void area(const osmium::Area&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void changeset(const osmium::Changeset&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void tag_list(const osmium::TagList&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void way_node_list(const osmium::WayNodeList&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation_member_list(const osmium::RelationMemberList&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void outer_ring(const osmium::OuterRing&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void inner_ring(const osmium::InnerRing&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void changeset_discussion(const osmium::ChangesetDiscussion&) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush() const {
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class Handler
|
|
||||||
|
|
||||||
} // namespace handler
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_HANDLER_HPP
|
|
@ -1,128 +0,0 @@
|
|||||||
#ifndef OSMIUM_HANDLER_CHAIN_HPP
|
|
||||||
#define OSMIUM_HANDLER_CHAIN_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <tuple>
|
|
||||||
|
|
||||||
#include <osmium/handler.hpp>
|
|
||||||
|
|
||||||
#define OSMIUM_CHAIN_HANDLER_CALL(_func_, _type_) \
|
|
||||||
template <int N, int SIZE, typename THandlers> \
|
|
||||||
struct call_ ## _func_ { \
|
|
||||||
void operator()(THandlers& handlers, osmium::_type_& object) { \
|
|
||||||
std::get<N>(handlers)._func_(object); \
|
|
||||||
call_ ## _func_<N+1, SIZE, THandlers>()(handlers, object); \
|
|
||||||
} \
|
|
||||||
}; \
|
|
||||||
template <int SIZE, typename THandlers> \
|
|
||||||
struct call_ ## _func_<SIZE, SIZE, THandlers> { \
|
|
||||||
void operator()(THandlers&, osmium::_type_&) {} \
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
class Node;
|
|
||||||
class Way;
|
|
||||||
class Relation;
|
|
||||||
class Area;
|
|
||||||
class Changeset;
|
|
||||||
|
|
||||||
namespace handler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This handler allows chaining of any number of handlers into a single
|
|
||||||
* handler.
|
|
||||||
*/
|
|
||||||
template <typename... THandler>
|
|
||||||
class ChainHandler : public osmium::handler::Handler {
|
|
||||||
|
|
||||||
typedef std::tuple<THandler&...> handlers_type;
|
|
||||||
handlers_type m_handlers;
|
|
||||||
|
|
||||||
template <int N, int SIZE, typename THandlers>
|
|
||||||
struct call_flush {
|
|
||||||
void operator()(THandlers& handlers) {
|
|
||||||
std::get<N>(handlers).flush();
|
|
||||||
call_flush<N+1, SIZE, THandlers>()(handlers);
|
|
||||||
}
|
|
||||||
}; // struct call_flush
|
|
||||||
|
|
||||||
template <int SIZE, typename THandlers>
|
|
||||||
struct call_flush<SIZE, SIZE, THandlers> {
|
|
||||||
void operator()(THandlers&) {}
|
|
||||||
}; // struct call_flush
|
|
||||||
|
|
||||||
OSMIUM_CHAIN_HANDLER_CALL(node, Node)
|
|
||||||
OSMIUM_CHAIN_HANDLER_CALL(way, Way)
|
|
||||||
OSMIUM_CHAIN_HANDLER_CALL(relation, Relation)
|
|
||||||
OSMIUM_CHAIN_HANDLER_CALL(changeset, Changeset)
|
|
||||||
OSMIUM_CHAIN_HANDLER_CALL(area, Area)
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit ChainHandler(THandler&... handlers) :
|
|
||||||
m_handlers(handlers...) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void node(osmium::Node& node) {
|
|
||||||
call_node<0, sizeof...(THandler), handlers_type>()(m_handlers, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void way(osmium::Way& way) {
|
|
||||||
call_way<0, sizeof...(THandler), handlers_type>()(m_handlers, way);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation(osmium::Relation& relation) {
|
|
||||||
call_relation<0, sizeof...(THandler), handlers_type>()(m_handlers, relation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void changeset( osmium::Changeset& changeset) {
|
|
||||||
call_changeset<0, sizeof...(THandler), handlers_type>()(m_handlers, changeset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void area(osmium::Area& area) {
|
|
||||||
call_area<0, sizeof...(THandler), handlers_type>()(m_handlers, area);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush() {
|
|
||||||
call_flush<0, sizeof...(THandler), handlers_type>()(m_handlers);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class ChainHandler
|
|
||||||
|
|
||||||
} // namespace handler
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_HANDLER_CHAIN_HPP
|
|
@ -1,136 +0,0 @@
|
|||||||
#ifndef OSMIUM_HANDLER_CHECK_ORDER_HPP
|
|
||||||
#define OSMIUM_HANDLER_CHECK_ORDER_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <osmium/handler.hpp>
|
|
||||||
#include <osmium/osm/node.hpp>
|
|
||||||
#include <osmium/osm/relation.hpp>
|
|
||||||
#include <osmium/osm/types.hpp>
|
|
||||||
#include <osmium/osm/way.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception thrown when a method in the CheckOrder class detects
|
|
||||||
* that the input is out of order.
|
|
||||||
*/
|
|
||||||
struct out_of_order_error : public std::runtime_error {
|
|
||||||
|
|
||||||
out_of_order_error(const std::string& what) :
|
|
||||||
std::runtime_error(what) {
|
|
||||||
}
|
|
||||||
|
|
||||||
out_of_order_error(const char* what) :
|
|
||||||
std::runtime_error(what) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct out_of_order_error
|
|
||||||
|
|
||||||
namespace handler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler that can be used to check that an OSM file is ordered
|
|
||||||
* correctly. Ordered in this case refers to the usual order in OSM
|
|
||||||
* files: First nodes in the order of their IDs, then ways in the order
|
|
||||||
* of their IDs, then relations in the order or their IDs. IDs have to
|
|
||||||
* be unique for each type.
|
|
||||||
*
|
|
||||||
* To use this add a CheckOrder member variable to your handler and
|
|
||||||
* call the node(), way(), and relation() methods from your node(),
|
|
||||||
* way(), and relations() handlers, respectively. An out_of_order_error
|
|
||||||
* exception will be thrown when the input is not in order.
|
|
||||||
*/
|
|
||||||
class CheckOrder : public osmium::handler::Handler {
|
|
||||||
|
|
||||||
osmium::object_id_type m_max_node_id = std::numeric_limits<osmium::object_id_type>::min();
|
|
||||||
osmium::object_id_type m_max_way_id = std::numeric_limits<osmium::object_id_type>::min();
|
|
||||||
osmium::object_id_type m_max_relation_id = std::numeric_limits<osmium::object_id_type>::min();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void node(const osmium::Node& node) {
|
|
||||||
if (m_max_way_id > 0) {
|
|
||||||
throw out_of_order_error("Found a node after a way.");
|
|
||||||
}
|
|
||||||
if (m_max_relation_id > 0) {
|
|
||||||
throw out_of_order_error("Found a node after a relation.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_max_node_id >= node.id()) {
|
|
||||||
throw out_of_order_error("Node IDs out of order.");
|
|
||||||
}
|
|
||||||
m_max_node_id = node.id();
|
|
||||||
}
|
|
||||||
|
|
||||||
void way(const osmium::Way& way) {
|
|
||||||
if (m_max_relation_id > 0) {
|
|
||||||
throw out_of_order_error("Found a way after a relation.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_max_way_id >= way.id()) {
|
|
||||||
throw out_of_order_error("Way IDs out of order.");
|
|
||||||
}
|
|
||||||
m_max_way_id = way.id();
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation(const osmium::Relation& relation) {
|
|
||||||
if (m_max_relation_id >= relation.id()) {
|
|
||||||
throw out_of_order_error("Relation IDs out of order.");
|
|
||||||
}
|
|
||||||
m_max_relation_id = relation.id();
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::object_id_type max_node_id() const noexcept {
|
|
||||||
return m_max_node_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::object_id_type max_way_id() const noexcept {
|
|
||||||
return m_max_way_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
osmium::object_id_type max_relation_id() const noexcept {
|
|
||||||
return m_max_relation_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class CheckOrder
|
|
||||||
|
|
||||||
} // namespace handler
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_HANDLER_CHECK_ORDER_HPP
|
|
@ -1,111 +0,0 @@
|
|||||||
#ifndef OSMIUM_HANDLER_DISK_STORE_HPP
|
|
||||||
#define OSMIUM_HANDLER_DISK_STORE_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
#include <osmium/handler.hpp>
|
|
||||||
#include <osmium/index/map.hpp>
|
|
||||||
#include <osmium/io/detail/read_write.hpp>
|
|
||||||
#include <osmium/memory/buffer.hpp>
|
|
||||||
#include <osmium/memory/item_iterator.hpp>
|
|
||||||
#include <osmium/osm/node.hpp>
|
|
||||||
#include <osmium/osm/relation.hpp>
|
|
||||||
#include <osmium/osm/types.hpp>
|
|
||||||
#include <osmium/osm/way.hpp>
|
|
||||||
#include <osmium/visitor.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace handler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Note: This handler will only work if either all object IDs are
|
|
||||||
* positive or all object IDs are negative.
|
|
||||||
*/
|
|
||||||
class DiskStore : public osmium::handler::Handler {
|
|
||||||
|
|
||||||
typedef osmium::index::map::Map<unsigned_object_id_type, size_t> offset_index_type;
|
|
||||||
|
|
||||||
size_t m_offset = 0;
|
|
||||||
int m_data_fd;
|
|
||||||
|
|
||||||
offset_index_type& m_node_index;
|
|
||||||
offset_index_type& m_way_index;
|
|
||||||
offset_index_type& m_relation_index;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit DiskStore(int data_fd, offset_index_type& node_index, offset_index_type& way_index, offset_index_type& relation_index) :
|
|
||||||
m_data_fd(data_fd),
|
|
||||||
m_node_index(node_index),
|
|
||||||
m_way_index(way_index),
|
|
||||||
m_relation_index(relation_index) {
|
|
||||||
}
|
|
||||||
|
|
||||||
DiskStore(const DiskStore&) = delete;
|
|
||||||
DiskStore& operator=(const DiskStore&) = delete;
|
|
||||||
|
|
||||||
~DiskStore() noexcept = default;
|
|
||||||
|
|
||||||
void node(const osmium::Node& node) {
|
|
||||||
m_node_index.set(node.positive_id(), m_offset);
|
|
||||||
m_offset += node.byte_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void way(const osmium::Way& way) {
|
|
||||||
m_way_index.set(way.positive_id(), m_offset);
|
|
||||||
m_offset += way.byte_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation(const osmium::Relation& relation) {
|
|
||||||
m_relation_index.set(relation.positive_id(), m_offset);
|
|
||||||
m_offset += relation.byte_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX
|
|
||||||
void operator()(const osmium::memory::Buffer& buffer) {
|
|
||||||
osmium::io::detail::reliable_write(m_data_fd, buffer.data(), buffer.committed());
|
|
||||||
|
|
||||||
osmium::apply(buffer.begin(), buffer.end(), *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class DiskStore
|
|
||||||
|
|
||||||
} // namespace handler
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_HANDLER_DISK_STORE_HPP
|
|
@ -1,294 +0,0 @@
|
|||||||
#ifndef OSMIUM_HANDLER_DUMP_HPP
|
|
||||||
#define OSMIUM_HANDLER_DUMP_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <iomanip>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <osmium/handler.hpp>
|
|
||||||
#include <osmium/memory/collection.hpp>
|
|
||||||
#include <osmium/memory/item.hpp>
|
|
||||||
#include <osmium/osm/area.hpp>
|
|
||||||
#include <osmium/osm/box.hpp>
|
|
||||||
#include <osmium/osm/changeset.hpp>
|
|
||||||
#include <osmium/osm/item_type.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/node.hpp>
|
|
||||||
#include <osmium/osm/node_ref.hpp>
|
|
||||||
#include <osmium/osm/object.hpp>
|
|
||||||
#include <osmium/osm/relation.hpp>
|
|
||||||
#include <osmium/osm/tag.hpp>
|
|
||||||
#include <osmium/osm/timestamp.hpp>
|
|
||||||
#include <osmium/osm/way.hpp>
|
|
||||||
#include <osmium/visitor.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace handler {
|
|
||||||
|
|
||||||
class Dump : public osmium::handler::Handler {
|
|
||||||
|
|
||||||
std::ostream* m_out;
|
|
||||||
bool m_with_size;
|
|
||||||
std::string m_prefix;
|
|
||||||
|
|
||||||
void print_title(const char* title, const osmium::memory::Item& item) {
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< title
|
|
||||||
<< ":";
|
|
||||||
|
|
||||||
if (m_with_size) {
|
|
||||||
*m_out << " ["
|
|
||||||
<< item.byte_size()
|
|
||||||
<< "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
*m_out << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_meta(const osmium::OSMObject& object) {
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " id="
|
|
||||||
<< object.id()
|
|
||||||
<< "\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " version="
|
|
||||||
<< object.version()
|
|
||||||
<< "\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " uid="
|
|
||||||
<< object.uid()
|
|
||||||
<< "\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " user=|"
|
|
||||||
<< object.user()
|
|
||||||
<< "|\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " changeset="
|
|
||||||
<< object.changeset()
|
|
||||||
<< "\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " timestamp="
|
|
||||||
<< object.timestamp().to_iso()
|
|
||||||
<< "\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " visible="
|
|
||||||
<< (object.visible() ? "yes" : "no")
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
Dump dump(*m_out, m_with_size, m_prefix + " ");
|
|
||||||
osmium::apply(object.cbegin(), object.cend(), dump);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_location(const osmium::Node& node) {
|
|
||||||
const osmium::Location& location = node.location();
|
|
||||||
|
|
||||||
if (location) {
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " lon="
|
|
||||||
<< std::fixed
|
|
||||||
<< std::setprecision(7)
|
|
||||||
<< location.lon_without_check()
|
|
||||||
<< "\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " lat="
|
|
||||||
<< location.lat_without_check()
|
|
||||||
<< "\n";
|
|
||||||
} else {
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " lon=\n"
|
|
||||||
<< m_prefix
|
|
||||||
<< " lat=\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit Dump(std::ostream& out, bool with_size = true, const std::string& prefix = "") :
|
|
||||||
m_out(&out),
|
|
||||||
m_with_size(with_size),
|
|
||||||
m_prefix(prefix) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void tag_list(const osmium::TagList& tags) {
|
|
||||||
print_title("TAGS", tags);
|
|
||||||
for (const auto& tag : tags) {
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " k=|"
|
|
||||||
<< tag.key()
|
|
||||||
<< "| v=|"
|
|
||||||
<< tag.value()
|
|
||||||
<< "|"
|
|
||||||
<< "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void way_node_list(const osmium::WayNodeList& wnl) {
|
|
||||||
print_title("NODES", wnl);
|
|
||||||
for (const auto& node_ref : wnl) {
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " ref="
|
|
||||||
<< node_ref.ref();
|
|
||||||
if (node_ref.location()) {
|
|
||||||
*m_out << " pos="
|
|
||||||
<< node_ref.location();
|
|
||||||
}
|
|
||||||
*m_out << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation_member_list(const osmium::RelationMemberList& rml) {
|
|
||||||
print_title("MEMBERS", rml);
|
|
||||||
for (const auto& member : rml) {
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " type="
|
|
||||||
<< item_type_to_name(member.type())
|
|
||||||
<< " ref="
|
|
||||||
<< member.ref()
|
|
||||||
<< " role=|"
|
|
||||||
<< member.role()
|
|
||||||
<< "|\n";
|
|
||||||
if (member.full_member()) {
|
|
||||||
Dump dump(*m_out, m_with_size, m_prefix + " | ");
|
|
||||||
osmium::apply_item(member.get_object(), dump);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void outer_ring(const osmium::OuterRing& ring) {
|
|
||||||
print_title("OUTER RING", ring);
|
|
||||||
for (const auto& node_ref : ring) {
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " ref="
|
|
||||||
<< node_ref.ref();
|
|
||||||
if (node_ref.location()) {
|
|
||||||
*m_out << " pos="
|
|
||||||
<< node_ref.location();
|
|
||||||
}
|
|
||||||
*m_out << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void inner_ring(const osmium::InnerRing& ring) {
|
|
||||||
print_title("INNER RING", ring);
|
|
||||||
for (const auto& node_ref : ring) {
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " ref="
|
|
||||||
<< node_ref.ref();
|
|
||||||
if (node_ref.location()) {
|
|
||||||
*m_out << " pos="
|
|
||||||
<< node_ref.location();
|
|
||||||
}
|
|
||||||
*m_out << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void node(const osmium::Node& node) {
|
|
||||||
print_title("NODE", node);
|
|
||||||
print_meta(node);
|
|
||||||
print_location(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void way(const osmium::Way& way) {
|
|
||||||
print_title("WAY", way);
|
|
||||||
print_meta(way);
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation(const osmium::Relation& relation) {
|
|
||||||
print_title("RELATION", relation);
|
|
||||||
print_meta(relation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void area(const osmium::Area& area) {
|
|
||||||
print_title("AREA", area);
|
|
||||||
print_meta(area);
|
|
||||||
}
|
|
||||||
|
|
||||||
void changeset(const osmium::Changeset& changeset) {
|
|
||||||
print_title("CHANGESET", changeset);
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " id="
|
|
||||||
<< changeset.id()
|
|
||||||
<< "\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " num_changes="
|
|
||||||
<< changeset.num_changes()
|
|
||||||
<< "\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " uid="
|
|
||||||
<< changeset.uid()
|
|
||||||
<< "\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " user=|"
|
|
||||||
<< changeset.user()
|
|
||||||
<< "|\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " created_at="
|
|
||||||
<< changeset.created_at().to_iso()
|
|
||||||
<< "\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " closed_at="
|
|
||||||
<< changeset.closed_at().to_iso()
|
|
||||||
<< "\n";
|
|
||||||
*m_out << m_prefix
|
|
||||||
<< " bounds=";
|
|
||||||
|
|
||||||
if (changeset.bounds()) {
|
|
||||||
*m_out << '('
|
|
||||||
<< changeset.bounds().bottom_left().lon_without_check()
|
|
||||||
<< ','
|
|
||||||
<< changeset.bounds().bottom_left().lat_without_check()
|
|
||||||
<< ','
|
|
||||||
<< changeset.bounds().top_right().lon_without_check()
|
|
||||||
<< ','
|
|
||||||
<< changeset.bounds().top_right().lat_without_check()
|
|
||||||
<< ')';
|
|
||||||
} else {
|
|
||||||
*m_out << "(undefined)";
|
|
||||||
}
|
|
||||||
|
|
||||||
*m_out << "\n";
|
|
||||||
|
|
||||||
Dump dump(*m_out, m_with_size, m_prefix + " ");
|
|
||||||
osmium::apply(changeset.cbegin(), changeset.cend(), dump);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class Dump
|
|
||||||
|
|
||||||
} // namespace handler
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_HANDLER_DUMP_HPP
|
|
@ -1,180 +0,0 @@
|
|||||||
#ifndef OSMIUM_HANDLER_NODE_LOCATIONS_FOR_WAYS_HPP
|
|
||||||
#define OSMIUM_HANDLER_NODE_LOCATIONS_FOR_WAYS_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include <osmium/handler.hpp>
|
|
||||||
#include <osmium/index/index.hpp>
|
|
||||||
#include <osmium/index/map/dummy.hpp>
|
|
||||||
#include <osmium/osm/location.hpp>
|
|
||||||
#include <osmium/osm/node.hpp>
|
|
||||||
#include <osmium/osm/node_ref.hpp>
|
|
||||||
#include <osmium/osm/types.hpp>
|
|
||||||
#include <osmium/osm/way.hpp>
|
|
||||||
|
|
||||||
#include <osmium/index/node_locations_map.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace handler {
|
|
||||||
|
|
||||||
typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> dummy_type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler to retrieve locations from nodes and add them to ways.
|
|
||||||
*
|
|
||||||
* @tparam TStoragePosIDs Class that handles the actual storage of the node locations
|
|
||||||
* (for positive IDs). It must support the set(id, value) and
|
|
||||||
* get(id) methods.
|
|
||||||
* @tparam TStorageNegIDs Same but for negative IDs.
|
|
||||||
*/
|
|
||||||
template <typename TStoragePosIDs, typename TStorageNegIDs = dummy_type>
|
|
||||||
class NodeLocationsForWays : public osmium::handler::Handler {
|
|
||||||
|
|
||||||
static_assert(std::is_base_of<osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location>, TStoragePosIDs>::value, "Index class must be derived from osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location>");
|
|
||||||
|
|
||||||
static_assert(std::is_base_of<osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location>, TStorageNegIDs>::value, "Index class must be derived from osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location>");
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef TStoragePosIDs index_pos_type;
|
|
||||||
typedef TStorageNegIDs index_neg_type;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/// Object that handles the actual storage of the node locations (with positive IDs).
|
|
||||||
TStoragePosIDs& m_storage_pos;
|
|
||||||
|
|
||||||
/// Object that handles the actual storage of the node locations (with negative IDs).
|
|
||||||
TStorageNegIDs& m_storage_neg;
|
|
||||||
|
|
||||||
bool m_ignore_errors {false};
|
|
||||||
|
|
||||||
bool m_must_sort {false};
|
|
||||||
|
|
||||||
// It is okay to have this static dummy instance, even when using several threads,
|
|
||||||
// because it is read-only.
|
|
||||||
static dummy_type& get_dummy() {
|
|
||||||
static dummy_type instance;
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit NodeLocationsForWays(TStoragePosIDs& storage_pos,
|
|
||||||
TStorageNegIDs& storage_neg = get_dummy()) :
|
|
||||||
m_storage_pos(storage_pos),
|
|
||||||
m_storage_neg(storage_neg) {
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeLocationsForWays(const NodeLocationsForWays&) = delete;
|
|
||||||
NodeLocationsForWays& operator=(const NodeLocationsForWays&) = delete;
|
|
||||||
|
|
||||||
NodeLocationsForWays(NodeLocationsForWays&&) = default;
|
|
||||||
NodeLocationsForWays& operator=(NodeLocationsForWays&&) = default;
|
|
||||||
|
|
||||||
~NodeLocationsForWays() noexcept = default;
|
|
||||||
|
|
||||||
void ignore_errors() {
|
|
||||||
m_ignore_errors = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store the location of the node in the storage.
|
|
||||||
*/
|
|
||||||
void node(const osmium::Node& node) {
|
|
||||||
m_must_sort = true;
|
|
||||||
const osmium::object_id_type id = node.id();
|
|
||||||
if (id >= 0) {
|
|
||||||
m_storage_pos.set(static_cast<osmium::unsigned_object_id_type>( id), node.location());
|
|
||||||
} else {
|
|
||||||
m_storage_neg.set(static_cast<osmium::unsigned_object_id_type>(-id), node.location());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get location of node with given id.
|
|
||||||
*/
|
|
||||||
osmium::Location get_node_location(const osmium::object_id_type id) const {
|
|
||||||
if (id >= 0) {
|
|
||||||
return m_storage_pos.get(static_cast<osmium::unsigned_object_id_type>( id));
|
|
||||||
} else {
|
|
||||||
return m_storage_neg.get(static_cast<osmium::unsigned_object_id_type>(-id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve locations of all nodes in the way from storage and add
|
|
||||||
* them to the way object.
|
|
||||||
*/
|
|
||||||
void way(osmium::Way& way) {
|
|
||||||
if (m_must_sort) {
|
|
||||||
m_storage_pos.sort();
|
|
||||||
m_storage_neg.sort();
|
|
||||||
m_must_sort = false;
|
|
||||||
}
|
|
||||||
bool error = false;
|
|
||||||
for (auto& node_ref : way.nodes()) {
|
|
||||||
try {
|
|
||||||
node_ref.set_location(get_node_location(node_ref.ref()));
|
|
||||||
if (!node_ref.location()) {
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
} catch (osmium::not_found&) {
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (error && !m_ignore_errors) {
|
|
||||||
throw osmium::not_found("location for one or more nodes not found in node location index");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call clear on the location indexes. Makes the
|
|
||||||
* NodeLocationsForWays handler unusable. Used to explicitly free
|
|
||||||
* memory if thats needed.
|
|
||||||
*/
|
|
||||||
void clear() {
|
|
||||||
m_storage_pos.clear();
|
|
||||||
m_storage_neg.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class NodeLocationsForWays
|
|
||||||
|
|
||||||
} // namespace handler
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_HANDLER_NODE_LOCATIONS_FOR_WAYS_HPP
|
|
@ -1,106 +0,0 @@
|
|||||||
#ifndef OSMIUM_HANDLER_OBJECT_RELATIONS_HPP
|
|
||||||
#define OSMIUM_HANDLER_OBJECT_RELATIONS_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <osmium/handler.hpp>
|
|
||||||
#include <osmium/index/multimap.hpp>
|
|
||||||
#include <osmium/osm/node_ref.hpp>
|
|
||||||
#include <osmium/osm/item_type.hpp>
|
|
||||||
#include <osmium/osm/relation.hpp>
|
|
||||||
#include <osmium/osm/types.hpp>
|
|
||||||
#include <osmium/osm/way.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace handler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Note: This handler will only work if either all object IDs are
|
|
||||||
* positive or all object IDs are negative.
|
|
||||||
*/
|
|
||||||
class ObjectRelations : public osmium::handler::Handler {
|
|
||||||
|
|
||||||
typedef osmium::index::multimap::Multimap<unsigned_object_id_type, unsigned_object_id_type> index_type;
|
|
||||||
|
|
||||||
index_type& m_index_n2w;
|
|
||||||
index_type& m_index_n2r;
|
|
||||||
index_type& m_index_w2r;
|
|
||||||
index_type& m_index_r2r;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit ObjectRelations(index_type& n2w, index_type& n2r, index_type& w2r, index_type& r2r) :
|
|
||||||
m_index_n2w(n2w),
|
|
||||||
m_index_n2r(n2r),
|
|
||||||
m_index_w2r(w2r),
|
|
||||||
m_index_r2r(r2r) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectRelations(const ObjectRelations&) = delete;
|
|
||||||
ObjectRelations& operator=(const ObjectRelations&) = delete;
|
|
||||||
|
|
||||||
~ObjectRelations() noexcept = default;
|
|
||||||
|
|
||||||
void way(const osmium::Way& way) {
|
|
||||||
for (const auto& node_ref : way.nodes()) {
|
|
||||||
m_index_n2w.set(node_ref.positive_ref(), way.positive_id());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void relation(const osmium::Relation& relation) {
|
|
||||||
for (const auto& member : relation.members()) {
|
|
||||||
switch (member.type()) {
|
|
||||||
case osmium::item_type::node:
|
|
||||||
m_index_n2r.set(member.positive_ref(), relation.positive_id());
|
|
||||||
break;
|
|
||||||
case osmium::item_type::way:
|
|
||||||
m_index_w2r.set(member.positive_ref(), relation.positive_id());
|
|
||||||
break;
|
|
||||||
case osmium::item_type::relation:
|
|
||||||
m_index_r2r.set(member.positive_ref(), relation.positive_id());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class ObjectRelations
|
|
||||||
|
|
||||||
} // namespace handler
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_HANDLER_OBJECT_RELATIONS_HPP
|
|
@ -1,85 +0,0 @@
|
|||||||
#ifndef OSMIUM_INDEX_BOOL_VECTOR_HPP
|
|
||||||
#define OSMIUM_INDEX_BOOL_VECTOR_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace index {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Index storing one bit for each Id. The index automatically scales
|
|
||||||
* with the Ids stored. Default value is 'false'. Storage uses
|
|
||||||
* std::vector<bool> and needs a minimum of memory if the Ids are
|
|
||||||
* dense.
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
class BoolVector {
|
|
||||||
|
|
||||||
static_assert(std::is_unsigned<T>::value, "Needs unsigned type");
|
|
||||||
|
|
||||||
std::vector<bool> m_bits;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
BoolVector() = default;
|
|
||||||
|
|
||||||
BoolVector(const BoolVector&) = default;
|
|
||||||
BoolVector(BoolVector&&) = default;
|
|
||||||
BoolVector& operator=(const BoolVector&) = default;
|
|
||||||
BoolVector& operator=(BoolVector&&) = default;
|
|
||||||
|
|
||||||
~BoolVector() noexcept = default;
|
|
||||||
|
|
||||||
void set(T id, bool value = true) {
|
|
||||||
if (m_bits.size() <= id) {
|
|
||||||
m_bits.resize(id + 1024 * 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bits[id] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get(T id) const {
|
|
||||||
return id < m_bits.size() && m_bits[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class BoolVector
|
|
||||||
|
|
||||||
} // namespace index
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_INDEX_BOOL_VECTOR_HPP
|
|
@ -1,70 +0,0 @@
|
|||||||
#ifndef OSMIUM_INDEX_DETAIL_CREATE_MAP_WITH_FD_HPP
|
|
||||||
#define OSMIUM_INDEX_DETAIL_CREATE_MAP_WITH_FD_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace index {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T* create_map_with_fd(const std::vector<std::string>& config) {
|
|
||||||
if (config.size() == 1) {
|
|
||||||
return new T();
|
|
||||||
}
|
|
||||||
assert(config.size() > 1);
|
|
||||||
const std::string& filename = config[1];
|
|
||||||
int fd = ::open(filename.c_str(), O_CREAT | O_RDWR, 0644);
|
|
||||||
if (fd == -1) {
|
|
||||||
throw std::runtime_error(std::string("can't open file '") + filename + "': " + strerror(errno));
|
|
||||||
}
|
|
||||||
return new T(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
} // namespace index
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_INDEX_DETAIL_CREATE_MAP_WITH_FD_HPP
|
|
@ -1,67 +0,0 @@
|
|||||||
#ifndef OSMIUM_INDEX_DETAIL_MMAP_VECTOR_ANON_HPP
|
|
||||||
#define OSMIUM_INDEX_DETAIL_MMAP_VECTOR_ANON_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
|
|
||||||
#include <osmium/index/detail/mmap_vector_base.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class looks and behaves like STL vector, but uses mmap
|
|
||||||
* internally.
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
class mmap_vector_anon : public mmap_vector_base<T> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
mmap_vector_anon() :
|
|
||||||
mmap_vector_base<T>() {
|
|
||||||
}
|
|
||||||
|
|
||||||
~mmap_vector_anon() noexcept = default;
|
|
||||||
|
|
||||||
}; // class mmap_vector_anon
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // __linux__
|
|
||||||
|
|
||||||
#endif // OSMIUM_INDEX_DETAIL_MMAP_VECTOR_ANON_HPP
|
|
@ -1,180 +0,0 @@
|
|||||||
#ifndef OSMIUM_INDEX_DETAIL_MMAP_VECTOR_BASE_HPP
|
|
||||||
#define OSMIUM_INDEX_DETAIL_MMAP_VECTOR_BASE_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <new> // IWYU pragma: keep
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include <osmium/util/memory_mapping.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
constexpr size_t mmap_vector_size_increment = 1024 * 1024;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a base class for implementing classes that look like
|
|
||||||
* STL vector but use mmap internally. Do not use this class itself,
|
|
||||||
* use the derived classes mmap_vector_anon or mmap_vector_file.
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
class mmap_vector_base {
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
size_t m_size;
|
|
||||||
osmium::util::TypedMemoryMapping<T> m_mapping;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
mmap_vector_base(int fd, size_t capacity, size_t size = 0) :
|
|
||||||
m_size(size),
|
|
||||||
m_mapping(capacity, osmium::util::MemoryMapping::mapping_mode::write_shared, fd) {
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit mmap_vector_base(size_t capacity = mmap_vector_size_increment) :
|
|
||||||
m_size(0),
|
|
||||||
m_mapping(capacity) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~mmap_vector_base() noexcept = default;
|
|
||||||
|
|
||||||
typedef T value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef T* pointer;
|
|
||||||
typedef const T* const_pointer;
|
|
||||||
typedef T* iterator;
|
|
||||||
typedef const T* const_iterator;
|
|
||||||
|
|
||||||
void close() {
|
|
||||||
m_mapping.unmap();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t capacity() const noexcept {
|
|
||||||
return m_mapping.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const noexcept {
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const noexcept {
|
|
||||||
return m_size == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const T* data() const {
|
|
||||||
return m_mapping.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
T* data() {
|
|
||||||
return m_mapping.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator[](size_t n) {
|
|
||||||
return data()[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
T at(size_t n) const {
|
|
||||||
if (n >= m_size) {
|
|
||||||
throw std::out_of_range("out of range");
|
|
||||||
}
|
|
||||||
return data()[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() noexcept {
|
|
||||||
m_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shrink_to_fit() {
|
|
||||||
// XXX do something here
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_back(const T& value) {
|
|
||||||
if (m_size >= capacity()) {
|
|
||||||
resize(m_size+1);
|
|
||||||
}
|
|
||||||
data()[m_size] = value;
|
|
||||||
++m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reserve(size_t new_capacity) {
|
|
||||||
if (new_capacity > capacity()) {
|
|
||||||
m_mapping.resize(new_capacity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(size_t new_size) {
|
|
||||||
if (new_size > capacity()) {
|
|
||||||
reserve(new_size + osmium::detail::mmap_vector_size_increment);
|
|
||||||
}
|
|
||||||
if (new_size > size()) {
|
|
||||||
new (data() + size()) T[new_size - size()];
|
|
||||||
}
|
|
||||||
m_size = new_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin() noexcept {
|
|
||||||
return data();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end() noexcept {
|
|
||||||
return data() + m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin() const noexcept {
|
|
||||||
return data();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end() const noexcept {
|
|
||||||
return data() + m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cbegin() const noexcept {
|
|
||||||
return data();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cend() const noexcept {
|
|
||||||
return data() + m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class mmap_vector_base
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_INDEX_DETAIL_MMAP_VECTOR_BASE_HPP
|
|
@ -1,74 +0,0 @@
|
|||||||
#ifndef OSMIUM_INDEX_DETAIL_MMAP_VECTOR_FILE_HPP
|
|
||||||
#define OSMIUM_INDEX_DETAIL_MMAP_VECTOR_FILE_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <osmium/index/detail/mmap_vector_base.hpp>
|
|
||||||
#include <osmium/index/detail/tmpfile.hpp>
|
|
||||||
#include <osmium/util/file.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class looks and behaves like STL vector, but mmap's a file
|
|
||||||
* internally.
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
class mmap_vector_file : public mmap_vector_base<T> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
mmap_vector_file() :
|
|
||||||
mmap_vector_base<T>(
|
|
||||||
osmium::detail::create_tmp_file(),
|
|
||||||
osmium::detail::mmap_vector_size_increment) {
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit mmap_vector_file(int fd) :
|
|
||||||
mmap_vector_base<T>(
|
|
||||||
fd,
|
|
||||||
osmium::util::file_size(fd) / sizeof(T),
|
|
||||||
osmium::util::file_size(fd) / sizeof(T)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~mmap_vector_file() noexcept = default;
|
|
||||||
|
|
||||||
}; // class mmap_vector_file
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_INDEX_DETAIL_MMAP_VECTOR_FILE_HPP
|
|
@ -1,62 +0,0 @@
|
|||||||
#ifndef OSMIUM_INDEX_DETAIL_TMPFILE_HPP
|
|
||||||
#define OSMIUM_INDEX_DETAIL_TMPFILE_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <system_error>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create and open a temporary file. It is removed after opening.
|
|
||||||
*
|
|
||||||
* @returns File descriptor of temporary file.
|
|
||||||
* @throws std::system_error if something went wrong.
|
|
||||||
*/
|
|
||||||
inline int create_tmp_file() {
|
|
||||||
FILE* file = ::tmpfile();
|
|
||||||
if (!file) {
|
|
||||||
throw std::system_error(errno, std::system_category(), "tempfile failed");
|
|
||||||
}
|
|
||||||
return fileno(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_INDEX_DETAIL_TMPFILE_HPP
|
|
@ -1,246 +0,0 @@
|
|||||||
#ifndef OSMIUM_INDEX_DETAIL_VECTOR_MAP_HPP
|
|
||||||
#define OSMIUM_INDEX_DETAIL_VECTOR_MAP_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <osmium/index/index.hpp>
|
|
||||||
#include <osmium/index/map.hpp>
|
|
||||||
#include <osmium/io/detail/read_write.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace index {
|
|
||||||
|
|
||||||
namespace map {
|
|
||||||
|
|
||||||
template <typename TVector, typename TId, typename TValue>
|
|
||||||
class VectorBasedDenseMap : public Map<TId, TValue> {
|
|
||||||
|
|
||||||
TVector m_vector;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef TValue element_type;
|
|
||||||
typedef TVector vector_type;
|
|
||||||
typedef typename vector_type::iterator iterator;
|
|
||||||
typedef typename vector_type::const_iterator const_iterator;
|
|
||||||
|
|
||||||
VectorBasedDenseMap() :
|
|
||||||
m_vector() {
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit VectorBasedDenseMap(int fd) :
|
|
||||||
m_vector(fd) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~VectorBasedDenseMap() noexcept final = default;
|
|
||||||
|
|
||||||
void reserve(const size_t size) final {
|
|
||||||
m_vector.reserve(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(const TId id, const TValue value) final {
|
|
||||||
if (size() <= id) {
|
|
||||||
m_vector.resize(id+1);
|
|
||||||
}
|
|
||||||
m_vector[id] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TValue get(const TId id) const final {
|
|
||||||
try {
|
|
||||||
const TValue& value = m_vector.at(id);
|
|
||||||
if (value == osmium::index::empty_value<TValue>()) {
|
|
||||||
not_found_error(id);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
} catch (std::out_of_range&) {
|
|
||||||
not_found_error(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const final {
|
|
||||||
return m_vector.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t byte_size() const {
|
|
||||||
return m_vector.size() * sizeof(element_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t used_memory() const final {
|
|
||||||
return sizeof(TValue) * size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() final {
|
|
||||||
m_vector.clear();
|
|
||||||
m_vector.shrink_to_fit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_as_array(const int fd) final {
|
|
||||||
osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(m_vector.data()), byte_size());
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin() {
|
|
||||||
return m_vector.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end() {
|
|
||||||
return m_vector.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cbegin() const {
|
|
||||||
return m_vector.cbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cend() const {
|
|
||||||
return m_vector.cend();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin() const {
|
|
||||||
return m_vector.cbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end() const {
|
|
||||||
return m_vector.cend();
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class VectorBasedDenseMap
|
|
||||||
|
|
||||||
|
|
||||||
template <typename TId, typename TValue, template<typename...> class TVector>
|
|
||||||
class VectorBasedSparseMap : public Map<TId, TValue> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename std::pair<TId, TValue> element_type;
|
|
||||||
typedef TVector<element_type> vector_type;
|
|
||||||
typedef typename vector_type::iterator iterator;
|
|
||||||
typedef typename vector_type::const_iterator const_iterator;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
vector_type m_vector;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
VectorBasedSparseMap() :
|
|
||||||
m_vector() {
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit VectorBasedSparseMap(int fd) :
|
|
||||||
m_vector(fd) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~VectorBasedSparseMap() final = default;
|
|
||||||
|
|
||||||
void set(const TId id, const TValue value) final {
|
|
||||||
m_vector.push_back(element_type(id, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
const TValue get(const TId id) const final {
|
|
||||||
const element_type element {
|
|
||||||
id,
|
|
||||||
osmium::index::empty_value<TValue>()
|
|
||||||
};
|
|
||||||
const auto result = std::lower_bound(m_vector.begin(), m_vector.end(), element, [](const element_type& a, const element_type& b) {
|
|
||||||
return a.first < b.first;
|
|
||||||
});
|
|
||||||
if (result == m_vector.end() || result->first != id) {
|
|
||||||
not_found_error(id);
|
|
||||||
} else {
|
|
||||||
return result->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const final {
|
|
||||||
return m_vector.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t byte_size() const {
|
|
||||||
return m_vector.size() * sizeof(element_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t used_memory() const final {
|
|
||||||
return sizeof(element_type) * size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() final {
|
|
||||||
m_vector.clear();
|
|
||||||
m_vector.shrink_to_fit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sort() final {
|
|
||||||
std::sort(m_vector.begin(), m_vector.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_as_list(const int fd) final {
|
|
||||||
osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(m_vector.data()), byte_size());
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin() {
|
|
||||||
return m_vector.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end() {
|
|
||||||
return m_vector.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cbegin() const {
|
|
||||||
return m_vector.cbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cend() const {
|
|
||||||
return m_vector.cend();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin() const {
|
|
||||||
return m_vector.cbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end() const {
|
|
||||||
return m_vector.cend();
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class VectorBasedSparseMap
|
|
||||||
|
|
||||||
} // namespace map
|
|
||||||
|
|
||||||
} // namespace index
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_INDEX_DETAIL_VECTOR_MAP_HPP
|
|
@ -1,186 +0,0 @@
|
|||||||
#ifndef OSMIUM_INDEX_DETAIL_VECTOR_MULTIMAP_HPP
|
|
||||||
#define OSMIUM_INDEX_DETAIL_VECTOR_MULTIMAP_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <osmium/index/index.hpp>
|
|
||||||
#include <osmium/index/multimap.hpp>
|
|
||||||
#include <osmium/io/detail/read_write.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace index {
|
|
||||||
|
|
||||||
namespace multimap {
|
|
||||||
|
|
||||||
template <typename TId, typename TValue, template<typename...> class TVector>
|
|
||||||
class VectorBasedSparseMultimap : public Multimap<TId, TValue> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename std::pair<TId, TValue> element_type;
|
|
||||||
typedef TVector<element_type> vector_type;
|
|
||||||
typedef typename vector_type::iterator iterator;
|
|
||||||
typedef typename vector_type::const_iterator const_iterator;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
vector_type m_vector;
|
|
||||||
|
|
||||||
static bool is_removed(element_type& element) {
|
|
||||||
return element.second == osmium::index::empty_value<TValue>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
VectorBasedSparseMultimap() :
|
|
||||||
m_vector() {
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit VectorBasedSparseMultimap(int fd) :
|
|
||||||
m_vector(fd) {
|
|
||||||
}
|
|
||||||
|
|
||||||
~VectorBasedSparseMultimap() noexcept final = default;
|
|
||||||
|
|
||||||
void set(const TId id, const TValue value) final {
|
|
||||||
m_vector.push_back(element_type(id, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
void unsorted_set(const TId id, const TValue value) {
|
|
||||||
m_vector.push_back(element_type(id, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<iterator, iterator> get_all(const TId id) {
|
|
||||||
const element_type element {
|
|
||||||
id,
|
|
||||||
osmium::index::empty_value<TValue>()
|
|
||||||
};
|
|
||||||
return std::equal_range(m_vector.begin(), m_vector.end(), element, [](const element_type& a, const element_type& b) {
|
|
||||||
return a.first < b.first;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<const_iterator, const_iterator> get_all(const TId id) const {
|
|
||||||
const element_type element {
|
|
||||||
id,
|
|
||||||
osmium::index::empty_value<TValue>()
|
|
||||||
};
|
|
||||||
return std::equal_range(m_vector.cbegin(), m_vector.cend(), element, [](const element_type& a, const element_type& b) {
|
|
||||||
return a.first < b.first;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const final {
|
|
||||||
return m_vector.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t byte_size() const {
|
|
||||||
return m_vector.size() * sizeof(element_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t used_memory() const final {
|
|
||||||
return sizeof(element_type) * size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() final {
|
|
||||||
m_vector.clear();
|
|
||||||
m_vector.shrink_to_fit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sort() final {
|
|
||||||
std::sort(m_vector.begin(), m_vector.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove(const TId id, const TValue value) {
|
|
||||||
auto r = get_all(id);
|
|
||||||
for (auto it = r.first; it != r.second; ++it) {
|
|
||||||
if (it->second == value) {
|
|
||||||
it->second = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void consolidate() {
|
|
||||||
std::sort(m_vector.begin(), m_vector.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void erase_removed() {
|
|
||||||
m_vector.erase(
|
|
||||||
std::remove_if(m_vector.begin(), m_vector.end(), is_removed),
|
|
||||||
m_vector.end()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_as_list(const int fd) final {
|
|
||||||
osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(m_vector.data()), byte_size());
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin() {
|
|
||||||
return m_vector.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end() {
|
|
||||||
return m_vector.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cbegin() const {
|
|
||||||
return m_vector.cbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator cend() const {
|
|
||||||
return m_vector.cend();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin() const {
|
|
||||||
return m_vector.cbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end() const {
|
|
||||||
return m_vector.cend();
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class VectorBasedSparseMultimap
|
|
||||||
|
|
||||||
} // namespace multimap
|
|
||||||
|
|
||||||
} // namespace index
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_INDEX_DETAIL_VECTOR_MULTIMAP_HPP
|
|
100
third_party/libosmium/include/osmium/index/index.hpp
vendored
100
third_party/libosmium/include/osmium/index/index.hpp
vendored
@ -1,100 +0,0 @@
|
|||||||
#ifndef OSMIUM_INDEX_INDEX_HPP
|
|
||||||
#define OSMIUM_INDEX_INDEX_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <limits>
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <osmium/util/compatibility.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception signaling that an element could not be
|
|
||||||
* found in an index.
|
|
||||||
*/
|
|
||||||
struct not_found : public std::runtime_error {
|
|
||||||
|
|
||||||
not_found(const std::string& what) :
|
|
||||||
std::runtime_error(what) {
|
|
||||||
}
|
|
||||||
|
|
||||||
not_found(const char* what) :
|
|
||||||
std::runtime_error(what) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // struct not_found
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Indexing of OSM data, Locations, etc.
|
|
||||||
*/
|
|
||||||
namespace index {
|
|
||||||
|
|
||||||
template <typename TKey>
|
|
||||||
OSMIUM_NORETURN void not_found_error(TKey key) {
|
|
||||||
std::stringstream s;
|
|
||||||
s << "id " << key << " not found";
|
|
||||||
throw not_found(s.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some of the index classes need an "empty" value that can
|
|
||||||
* never appear in real data. This function must return this
|
|
||||||
* empty value for any class used as a value in an index.
|
|
||||||
* The default implementation returns a default constructed
|
|
||||||
* object, but it can be specialized.
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
inline constexpr T empty_value() {
|
|
||||||
return T{};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The size_t value in indexes is usually used for offsets
|
|
||||||
* into a buffer or file. It is unlikely that we ever need
|
|
||||||
* the full range, so the max value is a good "empty" value.
|
|
||||||
*/
|
|
||||||
template <>
|
|
||||||
inline constexpr size_t empty_value<size_t>() {
|
|
||||||
return std::numeric_limits<size_t>::max();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace index
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_INDEX_INDEX_HPP
|
|
275
third_party/libosmium/include/osmium/index/map.hpp
vendored
275
third_party/libosmium/include/osmium/index/map.hpp
vendored
@ -1,275 +0,0 @@
|
|||||||
#ifndef OSMIUM_INDEX_MAP_HPP
|
|
||||||
#define OSMIUM_INDEX_MAP_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <functional>
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <osmium/util/compatibility.hpp>
|
|
||||||
#include <osmium/util/string.hpp>
|
|
||||||
|
|
||||||
namespace osmium {
|
|
||||||
|
|
||||||
namespace index {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Key-value containers with unique integer values for a key
|
|
||||||
*/
|
|
||||||
namespace map {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This abstract class defines an interface to storage classes
|
|
||||||
* intended for storing small pieces of data (such as coordinates)
|
|
||||||
* indexed by a positive integer (such as an object ID). The
|
|
||||||
* storage must be very space efficient and able to scale to billions
|
|
||||||
* of objects.
|
|
||||||
*
|
|
||||||
* Subclasses have different implementations that store the
|
|
||||||
* data in different ways in memory and/or on disk. Some storage
|
|
||||||
* classes are better suited when working with the whole planet,
|
|
||||||
* some are better for data extracts.
|
|
||||||
*
|
|
||||||
* Note that these classes are not required to track "empty" fields.
|
|
||||||
* When reading data you have to be sure you have put something in
|
|
||||||
* there before.
|
|
||||||
*
|
|
||||||
* A typical use for this and derived classes is storage of node
|
|
||||||
* locations indexed by node ID. These indexes will only work
|
|
||||||
* on 64 bit systems if used in this case. 32 bit systems just
|
|
||||||
* can't address that much memory!
|
|
||||||
*
|
|
||||||
* @tparam TId Id type, usually osmium::unsigned_object_id_type,
|
|
||||||
* must be an unsigned integral type.
|
|
||||||
* @tparam TValue Value type, usually osmium::Location or size_t.
|
|
||||||
* Copied by value, so should be "small" type.
|
|
||||||
*/
|
|
||||||
template <typename TId, typename TValue>
|
|
||||||
class Map {
|
|
||||||
|
|
||||||
static_assert(std::is_integral<TId>::value && std::is_unsigned<TId>::value,
|
|
||||||
"TId template parameter for class Map must be unsigned integral type");
|
|
||||||
|
|
||||||
Map(const Map&) = delete;
|
|
||||||
Map& operator=(const Map&) = delete;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
Map(Map&&) = default;
|
|
||||||
Map& operator=(Map&&) = default;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// The "key" type, usually osmium::unsigned_object_id_type.
|
|
||||||
typedef TId key_type;
|
|
||||||
|
|
||||||
/// The "value" type, usually a Location or size_t.
|
|
||||||
typedef TValue value_type;
|
|
||||||
|
|
||||||
Map() = default;
|
|
||||||
|
|
||||||
virtual ~Map() noexcept = default;
|
|
||||||
|
|
||||||
virtual void reserve(const size_t) {
|
|
||||||
// default implementation is empty
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the field with id to value.
|
|
||||||
virtual void set(const TId id, const TValue value) = 0;
|
|
||||||
|
|
||||||
/// Retrieve value by id. Does not check for overflow or empty fields.
|
|
||||||
virtual const TValue get(const TId id) const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the approximate number of items in the storage. The storage
|
|
||||||
* might allocate memory in blocks, so this size might not be
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the memory used for this storage in bytes. Note that this
|
|
||||||
* is not necessarily entirely accurate but an approximation.
|
|
||||||
* For storage classes that store the data in memory, this is
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear memory used for this storage. After this you can not
|
|
||||||
* use the storage container any more.
|
|
||||||
*/
|
|
||||||
virtual void clear() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sort data in map. Call this after writing all data and
|
|
||||||
* before reading. Not all implementations need this.
|
|
||||||
*/
|
|
||||||
virtual void sort() {
|
|
||||||
// default implementation is empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function could usually be const in derived classes,
|
|
||||||
// but not always. It could, for instance, sort internal data.
|
|
||||||
// This is why it is not declared const here.
|
|
||||||
virtual void dump_as_list(const int /*fd*/) {
|
|
||||||
throw std::runtime_error("can't dump as list");
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function could usually be const in derived classes,
|
|
||||||
// but not always. It could, for instance, sort internal data.
|
|
||||||
// This is why it is not declared const here.
|
|
||||||
virtual void dump_as_array(const int /*fd*/) {
|
|
||||||
throw std::runtime_error("can't dump as array");
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class Map
|
|
||||||
|
|
||||||
} // namespace map
|
|
||||||
|
|
||||||
template <typename TId, typename TValue>
|
|
||||||
class MapFactory {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef TId id_type;
|
|
||||||
typedef TValue value_type;
|
|
||||||
typedef osmium::index::map::Map<id_type, value_type> map_type;
|
|
||||||
typedef std::function<map_type*(const std::vector<std::string>&)> create_map_func;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::map<const std::string, create_map_func> m_callbacks;
|
|
||||||
|
|
||||||
MapFactory() = default;
|
|
||||||
|
|
||||||
MapFactory(const MapFactory&) = delete;
|
|
||||||
MapFactory& operator=(const MapFactory&) = delete;
|
|
||||||
|
|
||||||
MapFactory(MapFactory&&) = delete;
|
|
||||||
MapFactory& operator=(MapFactory&&) = delete;
|
|
||||||
|
|
||||||
OSMIUM_NORETURN static void error(const std::string& map_type_name) {
|
|
||||||
std::string error_message {"Support for map type '"};
|
|
||||||
error_message += map_type_name;
|
|
||||||
error_message += "' not compiled into this binary.";
|
|
||||||
throw std::runtime_error(error_message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
static MapFactory<id_type, value_type>& instance() {
|
|
||||||
static MapFactory<id_type, value_type> factory;
|
|
||||||
return factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool register_map(const std::string& map_type_name, create_map_func func) {
|
|
||||||
return m_callbacks.emplace(map_type_name, func).second;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool has_map_type(const std::string& map_type_name) const {
|
|
||||||
return m_callbacks.count(map_type_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> map_types() const {
|
|
||||||
std::vector<std::string> result;
|
|
||||||
|
|
||||||
for (const auto& cb : m_callbacks) {
|
|
||||||
result.push_back(cb.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(result.begin(), result.end());
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<map_type> create_map(const std::string& config_string) const {
|
|
||||||
std::vector<std::string> config = osmium::split_string(config_string, ',');
|
|
||||||
|
|
||||||
if (config.empty()) {
|
|
||||||
throw std::runtime_error("Need non-empty map type name.");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto it = m_callbacks.find(config[0]);
|
|
||||||
if (it != m_callbacks.end()) {
|
|
||||||
return std::unique_ptr<map_type>((it->second)(config));
|
|
||||||
}
|
|
||||||
|
|
||||||
error(config[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // class MapFactory
|
|
||||||
|
|
||||||
namespace map {
|
|
||||||
|
|
||||||
template <typename TId, typename TValue, template<typename, typename> class TMap>
|
|
||||||
struct create_map {
|
|
||||||
TMap<TId, TValue>* operator()(const std::vector<std::string>&) {
|
|
||||||
return new TMap<TId, TValue>();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace map
|
|
||||||
|
|
||||||
template <typename TId, typename TValue, template<typename, typename> class TMap>
|
|
||||||
inline bool register_map(const std::string& name) {
|
|
||||||
return osmium::index::MapFactory<TId, TValue>::instance().register_map(name, [](const std::vector<std::string>& config) {
|
|
||||||
return map::create_map<TId, TValue, TMap>()(config);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OSMIUM_CONCATENATE_DETAIL_(x, y) x##y
|
|
||||||
#define OSMIUM_CONCATENATE_(x, y) OSMIUM_CONCATENATE_DETAIL_(x, y)
|
|
||||||
|
|
||||||
#define REGISTER_MAP(id, value, klass, name) \
|
|
||||||
namespace osmium { namespace index { namespace detail { \
|
|
||||||
const bool OSMIUM_CONCATENATE_(registered_, name) = osmium::index::register_map<id, value, klass>(#name); \
|
|
||||||
inline bool OSMIUM_CONCATENATE_(get_registered_, name)() noexcept { \
|
|
||||||
return OSMIUM_CONCATENATE_(registered_, name); \
|
|
||||||
} \
|
|
||||||
} } }
|
|
||||||
|
|
||||||
} // namespace index
|
|
||||||
|
|
||||||
} // namespace osmium
|
|
||||||
|
|
||||||
#endif // OSMIUM_INDEX_MAP_HPP
|
|
@ -1,46 +0,0 @@
|
|||||||
#ifndef OSMIUM_INDEX_MAP_ALL_HPP
|
|
||||||
#define OSMIUM_INDEX_MAP_ALL_HPP
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
||||||
|
|
||||||
Copyright 2013-2016 Jochen Topf <jochen@topf.org> and others (see README).
|
|
||||||
|
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <osmium/index/map/dense_file_array.hpp> // IWYU pragma: keep
|
|
||||||
#include <osmium/index/map/dense_mem_array.hpp> // IWYU pragma: keep
|
|
||||||
#include <osmium/index/map/dense_mmap_array.hpp> // IWYU pragma: keep
|
|
||||||
#include <osmium/index/map/dummy.hpp> // IWYU pragma: keep
|
|
||||||
#include <osmium/index/map/sparse_file_array.hpp> // IWYU pragma: keep
|
|
||||||
#include <osmium/index/map/sparse_mem_array.hpp> // IWYU pragma: keep
|
|
||||||
#include <osmium/index/map/sparse_mem_map.hpp> // IWYU pragma: keep
|
|
||||||
#include <osmium/index/map/sparse_mem_table.hpp> // IWYU pragma: keep
|
|
||||||
#include <osmium/index/map/sparse_mmap_array.hpp> // IWYU pragma: keep
|
|
||||||
|
|
||||||
#endif // OSMIUM_INDEX_MAP_ALL_HPP
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user