diff -Nru osmcoastline-2.3.1/CHANGELOG.md osmcoastline-2.4.0/CHANGELOG.md --- osmcoastline-2.3.1/CHANGELOG.md 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/CHANGELOG.md 2022-12-22 08:34:24.000000000 +0000 @@ -13,6 +13,22 @@ ### Fixed +## [2.4.0] - 2022-12-22 + +### Added + +- `--format` option to `osmcoastline_filter` to set output file format. + +### Changed + +- Now needs at least C++14 and CMake 3.10. +- Various small code cleanups. + +### Fixed + +- Do not create empty polygons in water output. + + ## [2.3.1] - 2021-09-02 ### Added @@ -199,7 +215,8 @@ - Added man pages -[unreleased]: https://github.com/osmcode/osmium-tool/compare/v2.3.1...HEAD +[unreleased]: https://github.com/osmcode/osmium-tool/compare/v2.4.0...HEAD +[2.4.0]: https://github.com/osmcode/osmium-tool/compare/v2.3.1...v2.4.0 [2.3.1]: https://github.com/osmcode/osmium-tool/compare/v2.3.0...v2.3.1 [2.3.0]: https://github.com/osmcode/osmium-tool/compare/v2.2.4...v2.3.0 [2.2.4]: https://github.com/osmcode/osmium-tool/compare/v2.2.3...v2.2.4 diff -Nru osmcoastline-2.3.1/.clang-tidy osmcoastline-2.4.0/.clang-tidy --- osmcoastline-2.3.1/.clang-tidy 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/.clang-tidy 2022-12-22 08:34:24.000000000 +0000 @@ -1,14 +1,20 @@ --- -Checks: '*,-android-cloexec-*,-cert-err58-cpp,-cert-err60-cpp,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-type-vararg,-fuchsia-*,-google-runtime-references,-hicpp-avoid-c-arrays,-hicpp-no-array-decay,-hicpp-vararg,-llvmlibc-*,-misc-no-recursion,-modernize-avoid-c-arrays,-modernize-make-unique,-modernize-use-trailing-return-type,-readability-implicit-bool-cast,-readability-implicit-bool-conversion,-readability-magic-numbers' +Checks: '*,-altera-*,-android-cloexec-*,-bugprone-easily-swappable-parameters,-cert-err58-cpp,-cert-err60-cpp,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-type-vararg,-fuchsia-*,-google-runtime-references,-hicpp-avoid-c-arrays,-hicpp-no-array-decay,-hicpp-vararg,-llvmlibc-*,-misc-no-recursion,-modernize-avoid-c-arrays,-modernize-use-trailing-return-type,-readability-implicit-bool-cast,-readability-identifier-length,-readability-implicit-bool-conversion,-readability-magic-numbers,-readability-use-anyofallof' # # For a list of check options, see: # http://clang.llvm.org/extra/clang-tidy/checks/list.html # # Disabled checks: # +# altera-* +# Not applicable. +# # android-cloexec-* # O_CLOEXEC isn't available on Windows making this non-portable. # +# bugprone-easily-swappable-parameters +# When you need them, you need them. +# # cert-err58-cpp # Rather unlikely that this is a problem. # @@ -57,17 +63,20 @@ # misc-no-recursion # Nothing wrong about recursion. # -# modernize-make-unique -# This is a C++11 program and C++ doesn't have std::make_unique. -# # modernize-use-trailing-return-type # I am not quite that modern. # +# readability-identifier-length +# Sometimes short variable names are okay. +# # readability-implicit-bool-cast # Old name for readability-implicit-bool-conversion. # # readability-implicit-bool-conversion # I don't think this makes the code more readable. # +# readability-use-anyofallof +# Not necessarily more readable. +# WarningsAsErrors: '*' ... diff -Nru osmcoastline-2.3.1/cmake/FindOsmium.cmake osmcoastline-2.4.0/cmake/FindOsmium.cmake --- osmcoastline-2.3.1/cmake/FindOsmium.cmake 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/cmake/FindOsmium.cmake 2022-12-22 08:34:24.000000000 +0000 @@ -33,7 +33,7 @@ # 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 +# sparsehash - include if you use the sparsehash index (deprecated!) # lz4 - include support for LZ4 compression of PBF files # # You can check for success with something like this: @@ -224,6 +224,7 @@ #---------------------------------------------------------------------- # Component 'sparsehash' if(Osmium_USE_SPARSEHASH) + message(WARNING "Osmium: Use of Google SparseHash is deprecated. Please switch to a different index type.") find_path(SPARSEHASH_INCLUDE_DIR google/sparsetable) list(APPEND OSMIUM_EXTRA_FIND_VARS SPARSEHASH_INCLUDE_DIR) diff -Nru osmcoastline-2.3.1/CMakeLists.txt osmcoastline-2.4.0/CMakeLists.txt --- osmcoastline-2.3.1/CMakeLists.txt 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/CMakeLists.txt 2022-12-22 08:34:24.000000000 +0000 @@ -6,7 +6,7 @@ # #----------------------------------------------------------------------------- -cmake_minimum_required(VERSION 2.8 FATAL_ERROR) +cmake_minimum_required(VERSION 3.10 FATAL_ERROR) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") @@ -19,8 +19,8 @@ project(osmcoastline) set(OSMCOASTLINE_VERSION_MAJOR 2) -set(OSMCOASTLINE_VERSION_MINOR 3) -set(OSMCOASTLINE_VERSION_PATCH 1) +set(OSMCOASTLINE_VERSION_MINOR 4) +set(OSMCOASTLINE_VERSION_PATCH 0) set(OSMCOASTLINE_VERSION ${OSMCOASTLINE_VERSION_MAJOR}.${OSMCOASTLINE_VERSION_MINOR}.${OSMCOASTLINE_VERSION_PATCH}) @@ -71,12 +71,12 @@ #----------------------------------------------------------------------------- # -# Decide which C++ version to use (Minimum/default: C++11). +# Decide which C++ version to use (Minimum/default: C++14). # #----------------------------------------------------------------------------- if(NOT MSVC) if(NOT USE_CPP_VERSION) - set(USE_CPP_VERSION c++11) + set(USE_CPP_VERSION c++14) endif() message(STATUS "Use C++ version: ${USE_CPP_VERSION}") # following only available from cmake 2.8.12: @@ -155,7 +155,7 @@ # #----------------------------------------------------------------------------- message(STATUS "Looking for clang-tidy") -find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-12 clang-tidy-11 clang-tidy-10 clang-tidy-9 clang-tidy-8) +find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-16 clang-tidy-15 clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11) if(CLANG_TIDY) message(STATUS "Looking for clang-tidy - found ${CLANG_TIDY}") @@ -194,7 +194,7 @@ add_custom_target(cppcheck ${CPPCHECK} - --std=c++11 ${CPPCHECK_OPTIONS} + --std=c++14 ${CPPCHECK_OPTIONS} ${CPPCHECK_FILES} ) else() diff -Nru osmcoastline-2.3.1/debian/changelog osmcoastline-2.4.0/debian/changelog --- osmcoastline-2.3.1/debian/changelog 2022-12-01 13:36:39.000000000 +0000 +++ osmcoastline-2.4.0/debian/changelog 2022-12-22 13:54:17.000000000 +0000 @@ -1,3 +1,10 @@ +osmcoastline (2.4.0-1) unstable; urgency=medium + + * New upstream release. + * Update copyright file. + + -- Bas Couwenberg Thu, 22 Dec 2022 14:54:17 +0100 + osmcoastline (2.3.1-2) unstable; urgency=medium * Bump Standards-Version to 4.6.1, no changes. diff -Nru osmcoastline-2.3.1/debian/copyright osmcoastline-2.4.0/debian/copyright --- osmcoastline-2.3.1/debian/copyright 2021-01-08 15:19:04.000000000 +0000 +++ osmcoastline-2.4.0/debian/copyright 2022-12-22 13:53:58.000000000 +0000 @@ -4,9 +4,13 @@ Source: https://github.com/osmcode/osmcoastline Files: * -Copyright: 2012-2021, Jochen Topf +Copyright: 2012-2022, Jochen Topf License: GPL-3+ +Files: include/gdalcpp.hpp +Copyright: 2015-2021, Jochen Topf +License: BSL-1.0 + Files: debian/* Copyright: 2015, Bas Couwenberg License: GPL-2+ @@ -44,3 +48,27 @@ version 3 can be found in the file `/usr/share/common-licenses/GPL-3'. +License: BSL-1.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. diff -Nru osmcoastline-2.3.1/.github/actions/build/action.yml osmcoastline-2.4.0/.github/actions/build/action.yml --- osmcoastline-2.3.1/.github/actions/build/action.yml 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/.github/actions/build/action.yml 2022-12-22 08:34:24.000000000 +0000 @@ -1,21 +1,10 @@ name: Build runs: - using: composite - - steps: - - name: Create build directory - run: mkdir build - shell: bash - - - name: Configure - run: | - cmake -LA .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} - shell: bash - working-directory: build - - - name: Build - run: make VERBOSE=1 - shell: bash - working-directory: build + using: composite + steps: + - name: Build + run: make VERBOSE=1 + shell: bash + working-directory: build diff -Nru osmcoastline-2.3.1/.github/actions/cmake/action.yml osmcoastline-2.4.0/.github/actions/cmake/action.yml --- osmcoastline-2.3.1/.github/actions/cmake/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ osmcoastline-2.4.0/.github/actions/cmake/action.yml 2022-12-22 08:34:24.000000000 +0000 @@ -0,0 +1,15 @@ +name: CMake + +runs: + using: composite + steps: + - name: Create build directory + run: mkdir build + shell: bash + - name: Configure + run: | + cmake -LA .. \ + -DCMAKE_BUILD_TYPE=${BUILD_TYPE} + shell: bash + working-directory: build + diff -Nru osmcoastline-2.3.1/.github/actions/ctest/action.yml osmcoastline-2.4.0/.github/actions/ctest/action.yml --- osmcoastline-2.3.1/.github/actions/ctest/action.yml 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/.github/actions/ctest/action.yml 2022-12-22 08:34:24.000000000 +0000 @@ -1,10 +1,10 @@ name: ctest runs: - using: composite - steps: - - name: Test - run: ctest --output-on-failure - shell: bash - working-directory: build + using: composite + steps: + - name: Test + run: ctest --output-on-failure + shell: bash + working-directory: build diff -Nru osmcoastline-2.3.1/.github/actions/install-from-git/action.yml osmcoastline-2.4.0/.github/actions/install-from-git/action.yml --- osmcoastline-2.3.1/.github/actions/install-from-git/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ osmcoastline-2.4.0/.github/actions/install-from-git/action.yml 2022-12-22 08:34:24.000000000 +0000 @@ -0,0 +1,11 @@ +name: Install Prerequisites from git + +runs: + using: composite + steps: + - name: Install from git + run: | + git clone --quiet --depth 1 https://github.com/osmcode/libosmium.git ../libosmium + git clone --quiet --depth 1 https://github.com/mapbox/protozero.git ../protozero + shell: bash + diff -Nru osmcoastline-2.3.1/.github/actions/install-macos/action.yml osmcoastline-2.4.0/.github/actions/install-macos/action.yml --- osmcoastline-2.3.1/.github/actions/install-macos/action.yml 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/.github/actions/install-macos/action.yml 2022-12-22 08:34:24.000000000 +0000 @@ -2,7 +2,6 @@ runs: using: composite - steps: - name: Install homebrew packages run: | diff -Nru osmcoastline-2.3.1/.github/actions/install-ubuntu/action.yml osmcoastline-2.4.0/.github/actions/install-ubuntu/action.yml --- osmcoastline-2.3.1/.github/actions/install-ubuntu/action.yml 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/.github/actions/install-ubuntu/action.yml 2022-12-22 08:34:24.000000000 +0000 @@ -2,16 +2,15 @@ runs: using: composite - steps: - name: Install packages run: | - sudo apt-get update -q + sudo apt-get update -qq sudo apt-get install -yq \ - libgdal-dev \ - libgeos-dev \ - pandoc \ - spatialite-bin + libgdal-dev \ + libgeos-dev \ + pandoc \ + spatialite-bin shell: bash - name: Install from git run: | diff -Nru osmcoastline-2.3.1/.github/FUNDING.yml osmcoastline-2.4.0/.github/FUNDING.yml --- osmcoastline-2.3.1/.github/FUNDING.yml 1970-01-01 00:00:00.000000000 +0000 +++ osmcoastline-2.4.0/.github/FUNDING.yml 2022-12-22 08:34:24.000000000 +0000 @@ -0,0 +1 @@ +custom: "https://osmcode.org/sponsors.html" diff -Nru osmcoastline-2.3.1/.github/workflows/ci.yml osmcoastline-2.4.0/.github/workflows/ci.yml --- osmcoastline-2.3.1/.github/workflows/ci.yml 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/.github/workflows/ci.yml 2022-12-22 08:34:24.000000000 +0000 @@ -3,111 +3,195 @@ on: [ push, pull_request ] jobs: - ubuntu18-clang9-dev: - runs-on: ubuntu-18.04 - env: - CC: clang-9 - CXX: clang++-9 - BUILD_TYPE: Dev - steps: - - uses: actions/checkout@v2 - - uses: ./.github/actions/install-ubuntu - - uses: ./.github/actions/build - - uses: ./.github/actions/ctest - - ubuntu20-clang10-dev: - runs-on: ubuntu-20.04 - env: - CC: clang-10 - CXX: clang++-10 - BUILD_TYPE: Dev - steps: - - uses: actions/checkout@v2 - - uses: ./.github/actions/install-ubuntu - - uses: ./.github/actions/build - - uses: ./.github/actions/ctest - - ubuntu20-clang10-release: - runs-on: ubuntu-20.04 - env: - CC: clang-10 - CXX: clang++-10 - BUILD_TYPE: Release - steps: - - uses: actions/checkout@v2 - - uses: ./.github/actions/install-ubuntu - - uses: ./.github/actions/build - - uses: ./.github/actions/ctest - - ubuntu18-gcc7-dev: - runs-on: ubuntu-18.04 - env: - CC: gcc-7 - CXX: g++-7 - BUILD_TYPE: Dev - steps: - - uses: actions/checkout@v2 - - uses: ./.github/actions/install-ubuntu - - uses: ./.github/actions/build - - uses: ./.github/actions/ctest - - ubuntu20-gcc9-dev: - runs-on: ubuntu-20.04 - env: - CC: gcc-9 - CXX: g++-9 - BUILD_TYPE: Dev - steps: - - uses: actions/checkout@v2 - - uses: ./.github/actions/install-ubuntu - - uses: ./.github/actions/build - - uses: ./.github/actions/ctest - - ubuntu20-gcc10-release: - runs-on: ubuntu-20.04 - env: - CC: gcc-10 - CXX: g++-10 - BUILD_TYPE: Release - steps: - - uses: actions/checkout@v2 - - uses: ./.github/actions/install-ubuntu - - uses: ./.github/actions/build - - uses: ./.github/actions/ctest - - macos10-dev: - runs-on: macos-10.15 - env: - CC: clang - CXX: clang++ - BUILD_TYPE: Dev - steps: - - uses: actions/checkout@v2 - - uses: ./.github/actions/install-macos - - uses: ./.github/actions/build - - uses: ./.github/actions/ctest - - macos11-dev: - runs-on: macos-11.0 - env: - CC: clang - CXX: clang++ - BUILD_TYPE: Dev - steps: - - uses: actions/checkout@v2 - - uses: ./.github/actions/install-macos - - uses: ./.github/actions/build - - uses: ./.github/actions/ctest - - macos11-release: - runs-on: macos-11.0 + linux: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + name: [Ubuntu-18, Ubuntu-20, Ubuntu-22, Debian-10, Debian-11, Debian-Testing, Debian-Experimental, Fedora-35, Fedora-36] + build_type: [Dev] + cpp_compiler: [g++] + cpp_version: [c++14] + include: + - name: Ubuntu-18 + # Uses gcc 7.5.0, clang 6.0.0, cmake 3.10.2 + image: "ubuntu:18.04" + ubuntu: 18 + - name: Ubuntu-20 + # Uses gcc 9.3.0, clang 10.0.0, cmake 3.16.3 + image: "ubuntu:20.04" + ubuntu: 20 + - name: Ubuntu-22 + # Uses gcc 12.2.0, clang 15.0.2, cmake 3.24.2 + image: "ubuntu:22.04" + ubuntu: 22 + CXXFLAGS: -Wno-stringop-overread + - name: Debian-10 + # Uses gcc 8.3.0, clang 7.0.1, cmake 3.13.4 + image: "debian:buster" + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + cpp_version: c++17 + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + cpp_version: c++20 + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + c_compiler: clang + cpp_compiler: clang++ + cpp_version: c++17 + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + c_compiler: clang + cpp_compiler: clang++ + cpp_version: c++20 + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + build_type: RelWithDebInfo + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + c_compiler: clang + cpp_compiler: clang++ + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + c_compiler: clang + cpp_compiler: clang++ + CXXFLAGS: -fsanitize=address,undefined,integer -fno-sanitize-recover=all -fno-omit-frame-pointer + LDFLAGS: -fsanitize=address,undefined,integer + - name: Debian-Testing + # Uses gcc 10.3.0, clang 11.1.0, cmake 3.21.3 + image: "debian:testing" + CXXFLAGS: -Wno-stringop-overread + - name: Debian-Testing + # Uses gcc 10.3.0, clang 11.1.0, cmake 3.21.3 + image: "debian:testing" + c_compiler: clang + cpp_compiler: clang++ + - name: Debian-Experimental + # Uses gcc 11, clang 14, cmake 3.21.3 + image: "debian:experimental" + CXXFLAGS: -Wno-stringop-overread + - name: Debian-Experimental + # Uses gcc 11, clang 14, cmake 3.21.3 + image: "debian:experimental" + c_compiler: clang-14 + cpp_compiler: clang++-14 + - name: Fedora-35 + # Uses gcc 11.2.1, clang 12.0.1, cmake 3.20.5 + image: "fedora:35" + CXXFLAGS: -Wno-stringop-overread + - name: Fedora-36 + # Uses gcc 12.2.0, clang 14.0.5, cmake 3.24.2 + image: "fedora:36" + CXXFLAGS: -Wno-stringop-overread + container: + image: ${{ matrix.image }} + env: + LANG: en_US.UTF-8 + BUILD_TYPE: ${{ matrix.build_type }} + CC: ${{ matrix.c_compiler }} + CXX: ${{ matrix.cpp_compiler }} + CXXFLAGS: ${{ matrix.CXXFLAGS }} + LDFLAGS: ${{ matrix.LDFLAGS }} + CPP_VERSION: ${{ matrix.cpp_version }} + WITH_PROJ: ON + APT_LISTCHANGES_FRONTEND: none + DEBIAN_FRONTEND: noninteractive + steps: + - name: Prepare container (apt) + shell: bash + if: startsWith(matrix.image, 'debian:') || startsWith(matrix.image, 'ubuntu:') + run: | + apt-get update -qq + apt-get install -yq \ + clang \ + cmake \ + g++ \ + git \ + libbz2-dev \ + libexpat1-dev \ + libgdal-dev \ + libgeos-dev \ + liblz4-dev \ + make \ + spatialite-bin \ + zlib1g-dev + - name: Install compiler + shell: bash + if: matrix.cpp_compiler == 'clang++-14' + run: apt-get install -yq clang-14 + - name: Prepare container (dnf) + shell: bash + if: startsWith(matrix.image, 'fedora:') + run: | + dnf install --quiet --assumeyes \ + bzip2-devel \ + cmake \ + expat-devel \ + gcc-c++ \ + gdal-devel \ + geos-devel \ + git \ + lz4-devel \ + make \ + proj-devel \ + spatialite-tools \ + zlib-devel + - uses: actions/checkout@v3 + - uses: ./.github/actions/install-from-git + - uses: ./.github/actions/cmake + - uses: ./.github/actions/build + - uses: ./.github/actions/ctest + + ubuntu-latest: + runs-on: ubuntu-22.04 + env: + CC: clang-15 + CXX: clang++-15 + BUILD_TYPE: Dev + steps: + - name: Install new clang + run: | + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/llvm-snapshot.asc + sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main' + sudo apt-get update -qq + sudo apt-get install -yq clang-15 + shell: bash + - uses: actions/checkout@v3 + - uses: ./.github/actions/install-ubuntu + - uses: ./.github/actions/cmake + - uses: ./.github/actions/build + - uses: ./.github/actions/ctest + + macos: + strategy: + fail-fast: false + matrix: + os: + - "macos-11" + build_type: [Dev] + include: + - os: "macos-11" + build_type: Release + runs-on: ${{ matrix.os }} env: CC: clang CXX: clang++ - BUILD_TYPE: Release + BUILD_TYPE: ${{ matrix.build_type }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: ./.github/actions/install-macos + - uses: ./.github/actions/cmake - uses: ./.github/actions/build - uses: ./.github/actions/ctest diff -Nru osmcoastline-2.3.1/include/gdalcpp.hpp osmcoastline-2.4.0/include/gdalcpp.hpp --- osmcoastline-2.3.1/include/gdalcpp.hpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/include/gdalcpp.hpp 2022-12-22 08:34:24.000000000 +0000 @@ -5,11 +5,11 @@ C++11 wrapper classes for GDAL/OGR. -Version 1.2.0 +Version 1.3.0 https://github.com/joto/gdalcpp -Copyright 2015-2018 Jochen Topf +Copyright 2015-2021 Jochen Topf Boost Software License - Version 1.0 - August 17th, 2003 @@ -50,6 +50,12 @@ #include #include +#if defined(_MSC_VER) +# define GDALCPP_EXPORT __declspec(dllexport) +#else +# define GDALCPP_EXPORT __attribute__ ((visibility("default"))) +#endif + namespace gdalcpp { #if GDAL_VERSION_MAJOR >= 2 @@ -63,7 +69,7 @@ /** * Exception thrown for all errors in this class. */ - class gdal_error : public std::runtime_error { + class GDALCPP_EXPORT gdal_error : public std::runtime_error { std::string m_driver; std::string m_dataset; @@ -190,7 +196,7 @@ SRS() : m_spatial_reference() { - const auto result = m_spatial_reference.SetWellKnownGeogCS("WGS84"); + const auto result = m_spatial_reference.SetWellKnownGeogCS("CRS84"); if (result != OGRERR_NONE) { throw gdal_error{std::string{"can not initialize spatial reference system WGS84"}, result}; @@ -514,4 +520,6 @@ } // namespace gdalcpp +#undef GDALCPP_EXPORT + #endif // GDALCPP_HPP diff -Nru osmcoastline-2.3.1/man/osmcoastline_filter.md osmcoastline-2.4.0/man/osmcoastline_filter.md --- osmcoastline-2.3.1/man/osmcoastline_filter.md 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/man/osmcoastline_filter.md 2022-12-22 08:34:24.000000000 +0000 @@ -6,9 +6,9 @@ # SYNOPSIS -**osmcoastline_filter** --output=*OUTPUT_FILE* *INPUT-FILE* +**osmcoastline_filter** \--output=*OUTPUT_FILE* *INPUT-FILE* -**osmcoastline_filter** --help +**osmcoastline_filter** \--help # DESCRIPTION @@ -36,13 +36,19 @@ # OPTIONS --h, --help -: Display usage information +-f, \--format +: Set output format options (default: pbf). --o, --output=OSMFILE -: Where to write output (default: none) +-h, \--help +: Display usage information and exit. --V, --version +-o, \--output=OSMFILE +: Where to write output (default: none). + +-v, \--verbose +: Enable verbose output. + +-V, \--version : Display program version and license information. diff -Nru osmcoastline-2.3.1/man/osmcoastline.md osmcoastline-2.4.0/man/osmcoastline.md --- osmcoastline-2.3.1/man/osmcoastline.md 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/man/osmcoastline.md 2022-12-22 08:34:24.000000000 +0000 @@ -6,7 +6,7 @@ # SYNOPSIS -**osmcoastline** \[*OPTIONS*\] --output-database=*OUTPUT-DB* *INPUT-FILE* +**osmcoastline** \[*OPTIONS*\] \--output-database=*OUTPUT-DB* *INPUT-FILE* # DESCRIPTION @@ -22,10 +22,10 @@ # OPTIONS --h, --help +-h, \--help : Display usage information. --b, --bbox-overlap=OVERLAP +-b, \--bbox-overlap=OVERLAP : Polygons that are too large are split into two halves (recursively if need be). Where the polygons touch the OVERLAP is added, because two polygons just touching often lead to rendering problems. The value is given in the @@ -37,30 +37,30 @@ overlap by setting it to 0. Default is 0.0001 for WGS84 and 10 for Mercator. --c, --close-distance=DISTANCE +-c, \--close-distance=DISTANCE : **osmcoastline** assembles ways tagged `natural=coastline` into rings. Sometimes there is a gap in the coastline in the OSM data. **osmcoastline** will close this gap if it is smaller than DISTANCE. Use 0 to disable this feature. --d, --debug +-d, \--debug : Enable debugging output. --f, --overwrite +-f, \--overwrite : Overwrite output file if it already exists. --g, --gdal-driver=DRIVER +-g, \--gdal-driver=DRIVER : Allows user to select any GDAL driver. Only "SQLite", "GPKG" and "ESRI Shapefile" GDAL drivers have been tested. The default is "SQLite". --i, --no-index +-i, \--no-index : Do not create spatial indexes in output db. The default is to create those indexes. This makes the database larger, but data access is faster. --l, --output-lines +-l, \--output-lines : Output coastlines as lines to database file. --m, --max-points=NUM +-m, \--max-points=NUM : Set this to 0 to prevent splitting of large polygons and linestrings. If set to any other positive integer **osmcoastline** will try to split polygons/linestrings to not have more than this many points. Depending on @@ -68,23 +68,23 @@ sometimes not possible to get the polygons small enough. **osmcoastline** will warn you on STDERR if this is the case. Default is 1000. --o, --output-database=FILE +-o, \--output-database=FILE : Spatialite database file for output. This option must be set. --p, --output-polygons=land|water|both|none +-p, \--output-polygons=land|water|both|none : Which polygons to write out (default: land). --r, --output-rings +-r, \--output-rings : Output rings to database file. This is used for debugging. --s, --srs=EPSGCODE +-s, \--srs=EPSGCODE : Set spatial reference system/projection. Use 4326 for WGS84 or 3857 for "Web Mercator". If you want to use the data for the usual tiled web maps, 3857 is probably right. For other uses, especially if you want to re-project to some other projection, 4326 is probably right. Other projections are currently not supported. Default is 4326. --S, --write-segments=FILENAME +-S, \--write-segments=FILENAME : Write out all coastline segments to the specified file. Segments are connections between two points. The segments are written in an internal format intended for use with the **osmcoastline_segments** program @@ -92,11 +92,11 @@ those. Gaps are (possibly) closed in a later stage of running **osmcoastline**, but those closing segments will not be included. --v, --verbose +-v, \--verbose : Gives you detailed information on what **osmcoastline** is doing, including timing. --V, --version +-V, \--version : Display program version and license information. diff -Nru osmcoastline-2.3.1/man/osmcoastline_readmeta.md osmcoastline-2.4.0/man/osmcoastline_readmeta.md --- osmcoastline-2.3.1/man/osmcoastline_readmeta.md 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/man/osmcoastline_readmeta.md 2022-12-22 08:34:24.000000000 +0000 @@ -11,10 +11,10 @@ # OPTIONS --h, --help +-h, \--help : Display usage information. --V, --version +-V, \--version : Display program version and license information. diff -Nru osmcoastline-2.3.1/man/osmcoastline_segments.md osmcoastline-2.4.0/man/osmcoastline_segments.md --- osmcoastline-2.3.1/man/osmcoastline_segments.md 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/man/osmcoastline_segments.md 2022-12-22 08:34:24.000000000 +0000 @@ -12,26 +12,27 @@ # DESCRIPTION The **osmcoastline** program can write out all segments of the coastline into a -file (when started with the **-S, --write-segments=FILE** option). This program -can be used to compare two of those segment files in various ways to detect -coastline changes between different runs of the **osmcoastline** program. +file (when started with the **-S, \--write-segments=FILE** option). This +program can be used to compare two of those segment files in various ways to +detect coastline changes between different runs of the **osmcoastline** +program. # OPTIONS --h, --help +-h, \--help : Display usage information. --d, --dump +-d, \--dump : Dump segment list to stdout in plain text format. --g, --geom=FILENAME +-g, \--geom=FILENAME : Write segments to geometry file or database using OGR. --f, --format=FORMAT +-f, \--format=FORMAT : OGR format for writing out geometries. --V, --version +-V, \--version : Display program version and license information. diff -Nru osmcoastline-2.3.1/man/osmcoastline_ways.md osmcoastline-2.4.0/man/osmcoastline_ways.md --- osmcoastline-2.3.1/man/osmcoastline_ways.md 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/man/osmcoastline_ways.md 2022-12-22 08:34:24.000000000 +0000 @@ -11,10 +11,10 @@ # OPTIONS --h, --help +-h, \--help : Display usage information. --V, --version +-V, \--version : Display program version and license information. diff -Nru osmcoastline-2.3.1/osmcoastline_readmeta osmcoastline-2.4.0/osmcoastline_readmeta --- osmcoastline-2.3.1/osmcoastline_readmeta 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/osmcoastline_readmeta 2022-12-22 08:34:24.000000000 +0000 @@ -16,7 +16,7 @@ if [[ $# -ge 1 && ( $1 == "--version" || $1 == "-v" ) ]]; then echo "osmcoastline_readmeta version $OSMCOASTLINE_VERSION" - echo "Copyright (C) 2012-2021 Jochen Topf " + echo "Copyright (C) 2012-2022 Jochen Topf " echo "License: GNU GENERAL PUBLIC LICENSE Version 3 ." echo "This is free software: you are free to change and redistribute it." echo "There is NO WARRANTY, to the extent permitted by law."; diff -Nru osmcoastline-2.3.1/README.md osmcoastline-2.4.0/README.md --- osmcoastline-2.3.1/README.md 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/README.md 2022-12-22 08:34:24.000000000 +0000 @@ -39,9 +39,7 @@ https://gdal.org/ Debian/Ubuntu: libgdal1-dev (Must be built with Spatialite and GEOS support which is true for - Debian/Ubuntu packages. You need GDAL 1.7.0 or greater, consider using - https://wiki.ubuntu.com/UbuntuGIS when using Ubuntu to get newer - versions of GIS libraries.) + Debian/Ubuntu packages. You need GDAL 2 or greater. ### GEOS diff -Nru osmcoastline-2.3.1/src/coastline_polygons.cpp osmcoastline-2.4.0/src/coastline_polygons.cpp --- osmcoastline-2.3.1/src/coastline_polygons.cpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/coastline_polygons.cpp 2022-12-22 08:34:24.000000000 +0000 @@ -1,6 +1,6 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -30,6 +30,7 @@ #include #include +#include #include extern SRS srs; @@ -46,14 +47,14 @@ // make sure we are inside the bounds for the output SRS e.Intersect(srs.max_extent()); - std::unique_ptr ring{new OGRLinearRing()}; + auto ring = std::make_unique(); ring->addPoint(e.MinX, e.MinY); ring->addPoint(e.MinX, e.MaxY); ring->addPoint(e.MaxX, e.MaxY); ring->addPoint(e.MaxX, e.MinY); ring->closeRings(); - std::unique_ptr polygon{new OGRPolygon()}; + auto polygon = std::make_unique(); polygon->addRingDirectly(ring.release()); polygon->assignSpatialReference(srs.out()); @@ -133,6 +134,49 @@ } } +std::pair, std::unique_ptr> CoastlinePolygons::split_envelope(const OGREnvelope& envelope, int level, int num_points) const { + if (debug) { + std::cerr << "DEBUG: split_polygon(): depth=" + << level + << " envelope=(" + << envelope.MinX << ", " << envelope.MinY + << "),(" + << envelope.MaxX << ", " << envelope.MaxY + << ") num_points=" + << num_points + << "\n"; + } + + // These polygons will contain the bounding box of each half of the "polygon" polygon. + std::pair, std::unique_ptr> envelopes; + + if (envelope.MaxX - envelope.MinX < envelope.MaxY-envelope.MinY) { + if (m_expand >= (envelope.MaxY - envelope.MinY) / 4) { + std::cerr << "Not splitting polygon with " << num_points << " points on outer ring. It would not get smaller because --bbox-overlap/-b is set to high.\n"; + return envelopes; + } + + // split vertically + const double MidY = (envelope.MaxY + envelope.MinY) / 2; + + envelopes.first = create_rectangular_polygon(envelope.MinX, envelope.MinY, envelope.MaxX, MidY, m_expand); + envelopes.second = create_rectangular_polygon(envelope.MinX, MidY, envelope.MaxX, envelope.MaxY, m_expand); + } else { + if (m_expand >= (envelope.MaxX - envelope.MinX) / 4) { + std::cerr << "Not splitting polygon with " << num_points << " points on outer ring. It would not get smaller because --bbox-overlap/-b is set to high.\n"; + return envelopes; + } + + // split horizontally + const double MidX = (envelope.MaxX + envelope.MinX) / 2; + + envelopes.first = create_rectangular_polygon(envelope.MinX, envelope.MinY, MidX, envelope.MaxY, m_expand); + envelopes.second = create_rectangular_polygon(MidX, envelope.MinY, envelope.MaxX, envelope.MaxY, m_expand); + } + + return envelopes; +} + void CoastlinePolygons::split_polygon(std::unique_ptr&& polygon, int level) { if (level > m_max_split_depth) { m_max_split_depth = level; @@ -142,78 +186,45 @@ if (num_points <= m_max_points_in_polygon) { // do not split the polygon if it is small enough m_polygons.push_back(std::move(polygon)); - } else { - OGREnvelope envelope; - polygon->getEnvelope(&envelope); - if (debug) { - std::cerr << "DEBUG: split_polygon(): depth=" - << level - << " envelope=(" - << envelope.MinX << ", " << envelope.MinY - << "),(" - << envelope.MaxX << ", " << envelope.MaxY - << ") num_points=" - << num_points - << "\n"; - } - - // These polygons will contain the bounding box of each half of the "polygon" polygon. - std::unique_ptr b1; - std::unique_ptr b2; - - if (envelope.MaxX - envelope.MinX < envelope.MaxY-envelope.MinY) { - if (m_expand >= (envelope.MaxY - envelope.MinY) / 4) { - std::cerr << "Not splitting polygon with " << num_points << " points on outer ring. It would not get smaller because --bbox-overlap/-b is set to high.\n"; - m_polygons.push_back(std::move(polygon)); - return; - } - - // split vertically - const double MidY = (envelope.MaxY + envelope.MinY) / 2; + return; + } - b1 = create_rectangular_polygon(envelope.MinX, envelope.MinY, envelope.MaxX, MidY, m_expand); - b2 = create_rectangular_polygon(envelope.MinX, MidY, envelope.MaxX, envelope.MaxY, m_expand); - } else { - if (m_expand >= (envelope.MaxX - envelope.MinX) / 4) { - std::cerr << "Not splitting polygon with " << num_points << " points on outer ring. It would not get smaller because --bbox-overlap/-b is set to high.\n"; - m_polygons.push_back(std::move(polygon)); - return; - } + OGREnvelope envelope; + polygon->getEnvelope(&envelope); - // split horizontally - const double MidX = (envelope.MaxX + envelope.MinX) / 2; + auto const split_envelopes = split_envelope(envelope, level, num_points); + if (!split_envelopes.first) { + m_polygons.push_back(std::move(polygon)); + return; + } - b1 = create_rectangular_polygon(envelope.MinX, envelope.MinY, MidX, envelope.MaxY, m_expand); - b2 = create_rectangular_polygon(MidX, envelope.MinY, envelope.MaxX, envelope.MaxY, m_expand); + // Use intersection with bbox polygons to split polygon into two halfes + std::unique_ptr geom1{polygon->Intersection(split_envelopes.first.get())}; + std::unique_ptr geom2{polygon->Intersection(split_envelopes.second.get())}; + + if (geom1 && (geom1->getGeometryType() == wkbPolygon || geom1->getGeometryType() == wkbMultiPolygon) && + geom2 && (geom2->getGeometryType() == wkbPolygon || geom2->getGeometryType() == wkbMultiPolygon)) { + // split was successful, go on recursively + split_geometry(std::move(geom1), level + 1); + split_geometry(std::move(geom2), level + 1); + return; + } + + // split was not successful, output some debugging info and keep polygon before split + std::cerr << "Polygon split at depth " << level << " was not successful. Keeping un-split polygon.\n"; + m_polygons.push_back(std::move(polygon)); + if (debug) { + std::cerr << "DEBUG geom1=" << geom1.get() << " geom2=" << geom2.get() << "\n"; + if (geom1) { + std::cerr << "DEBUG geom1 type=" << geom1->getGeometryName() << "\n"; + if (geom1->getGeometryType() == wkbGeometryCollection) { + std::cerr << "DEBUG numGeometries=" << static_cast(geom1.get())->getNumGeometries() << "\n"; + } } - - // Use intersection with bbox polygons to split polygon into two halfes - std::unique_ptr geom1{polygon->Intersection(b1.get())}; - std::unique_ptr geom2{polygon->Intersection(b2.get())}; - - if (geom1 && (geom1->getGeometryType() == wkbPolygon || geom1->getGeometryType() == wkbMultiPolygon) && - geom2 && (geom2->getGeometryType() == wkbPolygon || geom2->getGeometryType() == wkbMultiPolygon)) { - // split was successful, go on recursively - split_geometry(std::move(geom1), level + 1); - split_geometry(std::move(geom2), level + 1); - } else { - // split was not successful, output some debugging info and keep polygon before split - std::cerr << "Polygon split at depth " << level << " was not successful. Keeping un-split polygon.\n"; - m_polygons.push_back(std::move(polygon)); - if (debug) { - std::cerr << "DEBUG geom1=" << geom1.get() << " geom2=" << geom2.get() << "\n"; - if (geom1) { - std::cerr << "DEBUG geom1 type=" << geom1->getGeometryName() << "\n"; - if (geom1->getGeometryType() == wkbGeometryCollection) { - std::cerr << "DEBUG numGeometries=" << static_cast(geom1.get())->getNumGeometries() << "\n"; - } - } - if (geom2) { - std::cerr << "DEBUG geom2 type=" << geom2->getGeometryName() << "\n"; - if (geom2->getGeometryType() == wkbGeometryCollection) { - std::cerr << "DEBUG numGeometries=" << static_cast(geom2.get())->getNumGeometries() << "\n"; - } - } + if (geom2) { + std::cerr << "DEBUG geom2 type=" << geom2->getGeometryName() << "\n"; + if (geom2->getGeometryType() == wkbGeometryCollection) { + std::cerr << "DEBUG numGeometries=" << static_cast(geom2.get())->getNumGeometries() << "\n"; } } } @@ -256,9 +267,9 @@ const int num = ring->getNumPoints(); assert(num > 2); - std::unique_ptr point1{new OGRPoint}; - std::unique_ptr point2{new OGRPoint}; - std::unique_ptr line{new OGRLineString}; + auto point1 = std::make_unique(); + auto point2 = std::make_unique(); + auto line = std::make_unique(); ring->getPoint(0, point1.get()); for (int i = 1; i < num; ++i) { @@ -268,7 +279,7 @@ if (line->getNumPoints() >= max_points || !added) { if (line->getNumPoints() >= 2) { - std::unique_ptr new_line{new OGRLineString}; + auto new_line = std::make_unique(); using std::swap; swap(line, new_line); add_line_to_output(std::move(new_line), ring->getSpatialReference()); @@ -293,16 +304,13 @@ } } -OGREnvelope env_west; -OGREnvelope env_east; - // Without this check there will be a very narrow sliver of water at the // antimeridian "cutting" into Antarctica. If this returns true, the geometry // is the polygon with this sliver and we don't add it to the output. -static bool antarctica_bogus(const OGRGeometry* geom) noexcept { +bool CoastlinePolygons::antarctica_bogus(const OGRGeometry* geom) noexcept { OGREnvelope envelope; geom->getEnvelope(&envelope); - return env_east.Contains(envelope) || env_west.Contains(envelope); + return m_env_east.Contains(envelope) || m_env_west.Contains(envelope); } void CoastlinePolygons::split_bbox(const OGREnvelope& envelope, polygon_vector_type&& v) { @@ -324,7 +332,10 @@ switch (geom->getGeometryType()) { case wkbPolygon: if (!antarctica_bogus(geom.get())) { - m_output.add_water_polygon(static_cast_unique_ptr(std::move(geom))); + auto polygon = static_cast_unique_ptr(std::move(geom)); + if (polygon->getExteriorRing()) { + m_output.add_water_polygon(std::move(polygon)); + } } break; case wkbMultiPolygon: { @@ -451,25 +462,25 @@ void CoastlinePolygons::output_water_polygons() { if (srs.is_wgs84()) { - env_west.MinX = -180.0; - env_west.MinY = -90.0; - env_west.MaxX = -179.9998; - env_west.MaxY = -77.0; - - env_east.MinX = 179.9998; - env_east.MinY = -90.0; - env_east.MaxX = 180.0; - env_east.MaxY = -77.0; + m_env_west.MinX = -180.0; + m_env_west.MinY = -90.0; + m_env_west.MaxX = -179.9998; + m_env_west.MaxY = -77.0; + + m_env_east.MinX = 179.9998; + m_env_east.MinY = -90.0; + m_env_east.MaxX = 180.0; + m_env_east.MaxY = -77.0; } else { - env_west.MinX = -20037508.342789244; - env_west.MinY = -20037508.342789244; - env_west.MaxX = -20037499.0; - env_west.MaxY = 14230070.0; - - env_east.MinX = 20037499.0; - env_east.MinY = -20037508.342789244; - env_east.MaxX = 20037508.342789244; - env_east.MaxY = 14230080.0; + m_env_west.MinX = -20037508.342789244; + m_env_west.MinY = -20037508.342789244; + m_env_west.MaxX = -20037499.0; + m_env_west.MaxY = 14230070.0; + + m_env_east.MinX = 20037499.0; + m_env_east.MinY = -20037508.342789244; + m_env_east.MaxX = 20037508.342789244; + m_env_east.MaxY = 14230080.0; } split_bbox(srs.max_extent(), std::move(m_polygons)); diff -Nru osmcoastline-2.3.1/src/coastline_polygons.hpp osmcoastline-2.4.0/src/coastline_polygons.hpp --- osmcoastline-2.3.1/src/coastline_polygons.hpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/coastline_polygons.hpp 2022-12-22 08:34:24.000000000 +0000 @@ -3,7 +3,7 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -64,6 +64,9 @@ */ polygon_vector_type m_polygons; + OGREnvelope m_env_west; + OGREnvelope m_env_east; + /** * Max depth after recursive splitting. */ @@ -73,6 +76,8 @@ void split_polygon(std::unique_ptr&& polygon, int level); void split_bbox(const OGREnvelope& envelope, polygon_vector_type&& v); + std::pair, std::unique_ptr> split_envelope(const OGREnvelope& envelope, int level, int num_points) const; + void add_line_to_output(std::unique_ptr line, OGRSpatialReference* srs) const; void output_polygon_ring_as_lines(int max_points, const OGRLinearRing* ring) const; @@ -119,6 +124,8 @@ /// Write all coastlines to the output database (as lines). void output_lines(int max_points) const; + bool antarctica_bogus(const OGRGeometry* geom) noexcept; + }; // class CoastlinePolygons #endif // COASTLINE_POLYGONS_HPP diff -Nru osmcoastline-2.3.1/src/coastline_ring_collection.cpp osmcoastline-2.4.0/src/coastline_ring_collection.cpp --- osmcoastline-2.3.1/src/coastline_ring_collection.cpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/coastline_ring_collection.cpp 2022-12-22 08:34:24.000000000 +0000 @@ -1,6 +1,6 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -229,11 +229,11 @@ const int omin = s2.first().y() < s2.second().y() ? s2.first().y() : s2.second().y(); const int omax = s2.first().y() < s2.second().y() ? s2.second().y() : s2.first().y(); - return !(tmin > omax || omin > tmax); + return tmin <= omax && omin <= tmax; } std::unique_ptr create_ogr_linestring(const osmium::Segment& segment) { - std::unique_ptr line{new OGRLineString}; + auto line = std::make_unique(); line->setNumPoints(2); line->setPoint(0, segment.first().lon(), segment.first().lat()); line->setPoint(1, segment.second().lon(), segment.second().lat()); @@ -302,7 +302,7 @@ break; } if (y_range_overlap(s1, s2)) { - osmium::Location i = intersection(s1, s2); + const auto i = intersection(s1, s2); if (i) { intersections.push_back(i); } @@ -312,7 +312,7 @@ } for (const auto& intersection : intersections) { - std::unique_ptr point{new OGRPoint(intersection.lon(), intersection.lat())}; + auto point = std::make_unique(intersection.lon(), intersection.lat()); output.add_error_point(std::move(point), "intersection"); } @@ -355,7 +355,7 @@ // Go through vector starting with the shortest connections and close rings // using the connections in turn. while (!connections.empty()) { - Connection conn = connections.back(); + const Connection conn = connections.back(); connections.pop_back(); // Invalidate all other connections using one of the same end points. @@ -378,7 +378,7 @@ output.add_error_point(s->ogr_first_point(), "fixed_end_point", s->first_node_id()); if (e->last_location() != s->first_location()) { - std::unique_ptr linestring{new OGRLineString}; + auto linestring = std::make_unique(); linestring->addPoint(e->last_location().lon(), e->last_location().lat()); linestring->addPoint(s->first_location().lon(), s->first_location().lat()); output.add_error_line(std::move(linestring), "added_line"); @@ -447,7 +447,7 @@ for (const auto& polygon : polygons) { const OGRLinearRing* exterior_ring = polygon->getExteriorRing(); assert(exterior_ring); - osmium::Location pos{exterior_ring->getX(0), exterior_ring->getY(0)}; + const osmium::Location pos{exterior_ring->getX(0), exterior_ring->getY(0)}; const auto rings_it = lower_bound(rings.begin(), rings.end(), lcrp_type{pos, nullptr}, comp); if (rings_it != rings.end()) { rings_it->second->set_outer(); diff -Nru osmcoastline-2.3.1/src/coastline_ring_collection.hpp osmcoastline-2.4.0/src/coastline_ring_collection.hpp --- osmcoastline-2.3.1/src/coastline_ring_collection.hpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/coastline_ring_collection.hpp 2022-12-22 08:34:24.000000000 +0000 @@ -3,7 +3,7 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. diff -Nru osmcoastline-2.3.1/src/coastline_ring.cpp osmcoastline-2.4.0/src/coastline_ring.cpp --- osmcoastline-2.3.1/src/coastline_ring.cpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/coastline_ring.cpp 2022-12-22 08:34:24.000000000 +0000 @@ -1,6 +1,6 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -97,12 +97,12 @@ void CoastlineRing::close_antarctica_ring(int epsg) { const double min = epsg == 4326 ? -90.0 : -85.0511288; - for (int lat = -78; lat > int(min); --lat) { - m_way_node_list.emplace_back(0, osmium::Location{-180.0, double(lat)}); + for (int lat = -78; lat > static_cast(min); --lat) { + m_way_node_list.emplace_back(0, osmium::Location{-180.0, static_cast(lat)}); } for (int lon = -180; lon < 180; ++lon) { - m_way_node_list.emplace_back(0, osmium::Location{double(lon), min}); + m_way_node_list.emplace_back(0, osmium::Location{static_cast(lon), min}); } if (epsg == 3857) { @@ -110,7 +110,7 @@ } for (auto lat = static_cast(min); lat < -78; ++lat) { - m_way_node_list.emplace_back(0, osmium::Location{180.0, double(lat)}); + m_way_node_list.emplace_back(0, osmium::Location{180.0, static_cast(lat)}); } m_way_node_list.push_back(m_way_node_list.front()); @@ -142,13 +142,13 @@ std::unique_ptr CoastlineRing::ogr_first_point() const { assert(!m_way_node_list.empty()); const osmium::NodeRef& node_ref = m_way_node_list.front(); - return std::unique_ptr{new OGRPoint{node_ref.lon(), node_ref.lat()}}; + return std::make_unique(node_ref.lon(), node_ref.lat()); } std::unique_ptr CoastlineRing::ogr_last_point() const { assert(!m_way_node_list.empty()); const osmium::NodeRef& node_ref = m_way_node_list.back(); - return std::unique_ptr{new OGRPoint{node_ref.lon(), node_ref.lat()}}; + return std::make_unique(node_ref.lon(), node_ref.lat()); } // Pythagoras doesn't work on a round earth but that is ok here, we only need a @@ -168,7 +168,7 @@ } } -std::ostream& operator<<(std::ostream& out, CoastlineRing& cp) { +std::ostream& operator<<(std::ostream& out, const CoastlineRing& cp) { out << "CoastlineRing(ring_id=" << cp.ring_id() << ", nways=" << cp.nways() << ", npoints=" << cp.npoints() diff -Nru osmcoastline-2.3.1/src/coastline_ring.hpp osmcoastline-2.4.0/src/coastline_ring.hpp --- osmcoastline-2.3.1/src/coastline_ring.hpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/coastline_ring.hpp 2022-12-22 08:34:24.000000000 +0000 @@ -3,7 +3,7 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. diff -Nru osmcoastline-2.3.1/src/nodegrid2opl.cpp osmcoastline-2.4.0/src/nodegrid2opl.cpp --- osmcoastline-2.3.1/src/nodegrid2opl.cpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/nodegrid2opl.cpp 2022-12-22 08:34:24.000000000 +0000 @@ -1,6 +1,6 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -56,7 +56,7 @@ const int id_offset = 100; -static void add_node(std::vector& nodes, char c, double x, double y) { +static bool add_node(std::vector& nodes, char c, double x, double y) { static std::set ids; int id = id_offset; @@ -68,11 +68,12 @@ if (ids.count(id)) { std::cerr << "ID seen twice: " << c << " (" << id << ")\n"; - std::exit(1); + return false; } ids.insert(id); nodes.push_back("n" + std::to_string(id) + " v1 x" + std::to_string(x) + " y" + std::to_string(y) + "\n"); + return true; } int main() { @@ -87,7 +88,9 @@ for (std::string line; std::getline(std::cin, line);) { for (const auto c : line) { if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z')) { - add_node(nodes, c, offset + x * scale, offset + y * scale); + if (!add_node(nodes, c, offset + x * scale, offset + y * scale)) { + return 1; + } } ++x; } diff -Nru osmcoastline-2.3.1/src/options.cpp osmcoastline-2.4.0/src/options.cpp --- osmcoastline-2.3.1/src/options.cpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/options.cpp 2022-12-22 08:34:24.000000000 +0000 @@ -1,6 +1,6 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -60,6 +60,19 @@ << "\n"; } +static void print_version() { + std::cout << "osmcoastline " << get_osmcoastline_long_version() << "\n" + << get_libosmium_version() << '\n' + << "Supported PBF compression types:"; + for (const auto& type : osmium::io::supported_pbf_compression_types()) { + std::cout << " " << type; + } + std::cout << "\n\nCopyright (C) 2012-2022 Jochen Topf \n" + << "License: GNU GENERAL PUBLIC LICENSE Version 3 .\n" + << "This is free software: you are free to change and redistribute it.\n" + << "There is NO WARRANTY, to the extent permitted by law.\n"; +} + /** * Get EPSG code from text. This method knows about a few common cases * of specifying WGS84 or the "Web Mercator" SRS. More are currently @@ -80,7 +93,7 @@ std::exit(return_code_cmdline); } -Options::Options(int argc, char* argv[]) { +int Options::parse(int argc, char* argv[]) { static struct option long_options[] = { {"bbox-overlap", required_argument, nullptr, 'b'}, {"close-distance", required_argument, nullptr, 'c'}, @@ -113,9 +126,6 @@ break; case 'c': close_distance = std::atoi(optarg); // NOLINT(cert-err34-c) atoi is good enough for this use case - if (close_distance == 0) { - close_rings = false; - } break; case 'i': create_index = false; @@ -126,7 +136,7 @@ break; case 'h': print_help(); - std::exit(return_code_ok); + return return_code_ok; case 'g': driver = optarg; break; @@ -150,7 +160,7 @@ output_polygons = output_polygon_type::both; } else { std::cerr << "Unknown argument '" << optarg << "' for -p/--output-polygon option\n"; - std::exit(return_code_cmdline); + return return_code_cmdline; } break; case 'o': @@ -172,35 +182,26 @@ verbose = true; break; case 'V': - std::cout << "osmcoastline " << get_osmcoastline_long_version() << "\n" - << get_libosmium_version() << '\n' - << "Supported PBF compression types:"; - for (const auto& type : osmium::io::supported_pbf_compression_types()) { - std::cout << " " << type; - } - std::cout << "\n\nCopyright (C) 2012-2021 Jochen Topf \n" - << "License: GNU GENERAL PUBLIC LICENSE Version 3 .\n" - << "This is free software: you are free to change and redistribute it.\n" - << "There is NO WARRANTY, to the extent permitted by law.\n"; - std::exit(return_code_ok); + print_version(); + return return_code_ok; default: - std::exit(return_code_cmdline); + return return_code_cmdline; } } if (!split_large_polygons && (output_polygons == output_polygon_type::water || output_polygons == output_polygon_type::both)) { std::cerr << "Can not use -m/--max-points=0 when writing out water polygons\n"; - std::exit(return_code_cmdline); + return return_code_cmdline; } if (optind != argc - 1) { std::cerr << "Usage: osmcoastline [OPTIONS] OSMFILE\n"; - std::exit(return_code_cmdline); + return return_code_cmdline; } if (output_database.empty()) { std::cerr << "Missing --output-database/-o option.\n"; - std::exit(return_code_cmdline); + return return_code_cmdline; } if (bbox_overlap == -1) { @@ -212,5 +213,7 @@ } inputfile = argv[optind]; + + return -1; } diff -Nru osmcoastline-2.3.1/src/options.hpp osmcoastline-2.4.0/src/options.hpp --- osmcoastline-2.3.1/src/options.hpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/options.hpp 2022-12-22 08:34:24.000000000 +0000 @@ -3,7 +3,7 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -48,9 +48,6 @@ */ double close_distance = 1.0; - /// Attempt to close unclosed rings? - bool close_rings = true; - /// Add spatial index to Spatialite database tables? bool create_index = true; @@ -96,7 +93,7 @@ /// Name of optional segment file std::string segmentfile; - Options(int argc, char* argv[]); + int parse(int argc, char* argv[]); }; // struct Options diff -Nru osmcoastline-2.3.1/src/osmcoastline.cpp osmcoastline-2.4.0/src/osmcoastline.cpp --- osmcoastline-2.3.1/src/osmcoastline.cpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/osmcoastline.cpp 2022-12-22 08:34:24.000000000 +0000 @@ -1,6 +1,6 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -69,6 +69,42 @@ /* ================================================== */ +void add_polygons_in_multi_to(polygon_vector_type *polygons, + std::unique_ptr mega_geometry, + OutputDatabase& output, + unsigned int* warnings, unsigned int* errors) { + // This isn't an owning pointer on purpose. We are going to "steal" parts + // of the geometry a few lines below but only mark them as unowned farther + // below when we are calling removeGeometry() on it. If this was an + // owning pointer we'd get a double free if there is an error. + auto* mega_multipolygon = static_cast(mega_geometry.release()); + + polygons->reserve(mega_multipolygon->getNumGeometries()); + for (int i = 0; i < mega_multipolygon->getNumGeometries(); ++i) { + OGRGeometry* geom = mega_multipolygon->getGeometryRef(i); + assert(geom); + assert(geom->getGeometryType() == wkbPolygon); + std::unique_ptr p{static_cast(geom)}; + if (p->IsValid()) { + polygons->push_back(std::move(p)); + } else { + output.add_error_line(make_unique_ptr_clone(p->getExteriorRing()), "invalid"); + std::unique_ptr buf0{p->Buffer(0)}; + if (buf0 && buf0->getGeometryType() == wkbPolygon && buf0->IsValid()) { + buf0->assignSpatialReference(srs.wgs84()); + polygons->push_back(static_cast_unique_ptr(std::move(buf0))); + (*warnings)++; + } else { + std::cerr << "Ignoring invalid polygon geometry.\n"; + (*errors)++; + } + } + } + + mega_multipolygon->removeGeometry(-1, FALSE); + delete mega_multipolygon; // NOLINT(cppcoreguidelines-owning-memory) +} + /** * This function assembles all the coastline rings into one huge multipolygon. */ @@ -84,7 +120,7 @@ if (debug) { std::cerr << "Calling organizePolygons()\n"; } - std::unique_ptr mega_geometry{OGRGeometryFactory::organizePolygons(&all_polygons[0], all_polygons.size(), &is_valid, options)}; + std::unique_ptr mega_geometry{OGRGeometryFactory::organizePolygons(all_polygons.data(), static_cast(all_polygons.size()), &is_valid, options)}; if (debug) { std::cerr << "organizePolygons() done (" << (is_valid ? "valid" : "invalid") << ")\n"; } @@ -105,37 +141,7 @@ } else if (mega_geometry->getGeometryType() != wkbMultiPolygon) { throw std::runtime_error{"mega geometry isn't a (multi)polygon. Something is very wrong!"}; } else { - - // This isn't an owning pointer on purpose. We are going to "steal" parts - // of the geometry a few lines below but only mark them as unowned farther - // below when we are calling removeGeometry() on it. If this was an - // owning pointer we'd get a double free if there is an error. - auto* mega_multipolygon = static_cast(mega_geometry.release()); - - polygons.reserve(mega_multipolygon->getNumGeometries()); - for (int i = 0; i < mega_multipolygon->getNumGeometries(); ++i) { - OGRGeometry* geom = mega_multipolygon->getGeometryRef(i); - assert(geom); - assert(geom->getGeometryType() == wkbPolygon); - std::unique_ptr p{static_cast(geom)}; - if (p->IsValid()) { - polygons.push_back(std::move(p)); - } else { - output.add_error_line(make_unique_ptr_clone(p->getExteriorRing()), "invalid"); - std::unique_ptr buf0{p->Buffer(0)}; - if (buf0 && buf0->getGeometryType() == wkbPolygon && buf0->IsValid()) { - buf0->assignSpatialReference(srs.wgs84()); - polygons.push_back(static_cast_unique_ptr(std::move(buf0))); - (*warnings)++; - } else { - std::cerr << "Ignoring invalid polygon geometry.\n"; - (*errors)++; - } - } - } - - mega_multipolygon->removeGeometry(-1, FALSE); - delete mega_multipolygon; // NOLINT(cppcoreguidelines-owning-memory) + add_polygons_in_multi_to(&polygons, std::move(mega_geometry), output, warnings, errors); } return polygons; @@ -145,7 +151,7 @@ /* ================================================== */ std::string memory_usage() { - osmium::MemoryUsage mem; + const osmium::MemoryUsage mem; std::ostringstream s; s << "Memory used: current: " << mem.current() << " MBytes, peak: " << mem.peak() << " MBytes\n"; return s.str(); @@ -154,10 +160,10 @@ /* ================================================== */ std::unique_ptr open_output_database(const std::string& driver, const std::string& name, const bool create_index) try { - return std::unique_ptr{new OutputDatabase{driver, name, srs, create_index}}; + return std::make_unique(driver, name, srs, create_index); } catch (const std::exception& e) { std::cerr << e.what() << '\n'; - std::exit(return_code_fatal); + return nullptr; } /* ================================================== */ @@ -168,7 +174,11 @@ unsigned int errors = 0; // Parse command line and setup 'options' object with them. - Options options{argc, argv}; + Options options; + const int result_code = options.parse(argc, argv); + if (result_code >= 0) { + return result_code; + } // The vout object is an output stream we can write to instead of // std::cerr. Nothing is written if we are not in verbose mode. @@ -184,7 +194,7 @@ vout << "Using SRS " << options.epsg << " for output. (Change with the --srs/s option.)\n"; if (!srs.set_output(options.epsg)) { std::cerr << "Setting up output transformation failed\n"; - std::exit(return_code_fatal); + return return_code_fatal; } // Optionally set up segments file @@ -194,7 +204,7 @@ segments_fd = ::open(options.segmentfile.c_str(), O_WRONLY | O_CREAT, 0666); // NOLINT(hicpp-signed-bitwise) if (segments_fd == -1) { std::cerr << "Couldn't open file '" << options.segmentfile << "' (" << std::strerror(errno) << ")\n"; - std::exit(return_code_fatal); + return return_code_fatal; } } @@ -212,6 +222,9 @@ } auto output_database = open_output_database(options.driver, options.output_database, options.create_index); + if (!output_database) { + return return_code_fatal; + } // The collection of all coastline rings we will be filling and then // operating on. @@ -222,7 +235,7 @@ // held by some intermediate datastructures is recovered after we don't // need them any more. vout << "Reading from file '" << options.inputfile << "'.\n"; - osmium::io::File infile{options.inputfile}; + const osmium::io::File infile{options.inputfile}; vout << "Reading ways (1st pass through input file)...\n"; osmium::io::Reader reader1{infile, osmium::osm_entity_bits::way}; @@ -278,18 +291,17 @@ reader2.close(); } catch (const std::exception& e) { std::cerr << e.what() << '\n'; - std::exit(return_code_fatal); + return return_code_fatal; } try { vout << "Checking for missing locations...\n"; - unsigned int missing_locations = coastline_rings.check_locations(options.debug); + const unsigned int missing_locations = coastline_rings.check_locations(options.debug); if (missing_locations) { vout << " There are " << missing_locations << " locations missing. Check that input file contains all nodes needed.\n"; - std::exit(return_code_error); - } else { - vout << " All locations are there.\n"; + return return_code_error; } + vout << " All locations are there.\n"; vout << memory_usage(); @@ -309,7 +321,7 @@ vout << " Did not find open Antarctica ring.\n"; } - if (options.close_rings) { + if (options.close_distance > 0) { vout << "Close broken rings... (Use --close-distance/-c 0 if you do not want this.)\n"; vout << " Closing if distance between nodes smaller than " << options.close_distance << ". (Set this with --close-distance/-c.)\n"; coastline_rings.close_rings(*output_database, options.debug, options.close_distance); @@ -330,7 +342,7 @@ } } catch (const std::exception& e) { std::cerr << e.what() << '\n'; - std::exit(return_code_fatal); + return return_code_fatal; } if (options.output_polygons != output_polygon_type::none || options.output_lines) { diff -Nru osmcoastline-2.3.1/src/osmcoastline_filter.cpp osmcoastline-2.4.0/src/osmcoastline_filter.cpp --- osmcoastline-2.3.1/src/osmcoastline_filter.cpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/osmcoastline_filter.cpp 2022-12-22 08:34:24.000000000 +0000 @@ -1,6 +1,6 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -49,6 +49,7 @@ void print_help() { std::cout << "Usage: osmcoastline_filter [OPTIONS] OSMFILE\n" << "\nOptions:\n" + << " -f, --format - Set output format (default: pbf)\n" << " -h, --help - This help message\n" << " -o, --output=OSMFILE - Where to write output (default: none)\n" << " -v, --verbose - Verbose output\n" @@ -58,9 +59,11 @@ int main(int argc, char* argv[]) { std::string output_filename; + std::string output_file_format{"pbf"}; bool verbose = false; static struct option long_options[] = { + {"format", required_argument, nullptr, 'f'}, {"help", no_argument, nullptr, 'h'}, {"output", required_argument, nullptr, 'o'}, {"verbose", no_argument, nullptr, 'v'}, @@ -69,15 +72,18 @@ }; while (true) { - const int c = getopt_long(argc, argv, "ho:vV", long_options, nullptr); + const int c = getopt_long(argc, argv, "f:ho:vV", long_options, nullptr); if (c == -1) { break; } switch (c) { + case 'f': + output_file_format = optarg; + break; case 'h': print_help(); - std::exit(return_code_ok); + return return_code_ok; case 'o': output_filename = optarg; break; @@ -86,24 +92,24 @@ break; case 'V': std::cout << "osmcoastline_filter " << get_osmcoastline_long_version() << " / " << get_libosmium_version() << '\n' - << "Copyright (C) 2012-2021 Jochen Topf \n" + << "Copyright (C) 2012-2022 Jochen Topf \n" << "License: GNU GENERAL PUBLIC LICENSE Version 3 .\n" << "This is free software: you are free to change and redistribute it.\n" << "There is NO WARRANTY, to the extent permitted by law.\n"; - std::exit(return_code_ok); + return return_code_ok; default: - std::exit(return_code_fatal); + return return_code_fatal; } } if (output_filename.empty()) { std::cerr << "Missing -o/--output=OSMFILE option\n"; - std::exit(return_code_cmdline); + return return_code_cmdline; } if (optind != argc - 1) { std::cerr << "Usage: osmcoastline_filter [OPTIONS] OSMFILE\n"; - std::exit(return_code_cmdline); + return return_code_cmdline; } try { @@ -116,11 +122,12 @@ header.set("generator", std::string{"osmcoastline_filter/"} + get_osmcoastline_version()); header.add_box(osmium::Box{-180.0, -90.0, 180.0, 90.0}); - osmium::io::File infile{argv[optind]}; + const osmium::io::File infile{argv[optind]}; vout << "Started osmcoastline_filter " << get_osmcoastline_long_version() << " / " << get_libosmium_version() << '\n'; - osmium::io::Writer writer{output_filename, header}; + const osmium::io::File output_file{output_filename, output_file_format}; + osmium::io::Writer writer{output_file, header}; auto output_it = osmium::io::make_output_iterator(writer); osmium::index::IdSetSmall ids; @@ -171,14 +178,16 @@ writer.close(); vout << "All done.\n"; - osmium::MemoryUsage mem; + const osmium::MemoryUsage mem; if (mem.current() > 0) { vout << "Memory used: current: " << mem.current() << " MBytes\n" << " peak: " << mem.peak() << " MBytes\n"; } } catch (const std::exception& e) { std::cerr << e.what() << '\n'; - std::exit(return_code_fatal); + return return_code_fatal; } + + return return_code_ok; } diff -Nru osmcoastline-2.3.1/src/osmcoastline_segments.cpp osmcoastline-2.4.0/src/osmcoastline_segments.cpp --- osmcoastline-2.3.1/src/osmcoastline_segments.cpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/osmcoastline_segments.cpp 2022-12-22 08:34:24.000000000 +0000 @@ -1,6 +1,6 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -74,7 +74,7 @@ if (::fstat(m_fd, &s) != 0) { throw std::system_error{errno, std::system_category(), std::string{"Can't get file size for '"} + m_filename + "'"}; } - return std::size_t(s.st_size); + return static_cast(s.st_size); } }; // class InputFile @@ -83,7 +83,7 @@ } void add_segment(gdalcpp::Layer& layer, int change, const osmium::UndirectedSegment& segment) { - auto linestring = std::unique_ptr{new OGRLineString()}; + auto linestring = std::make_unique(); linestring->addPoint(segment.first().lon(), segment.first().lat()); linestring->addPoint(segment.second().lon(), segment.second().lat()); @@ -143,15 +143,15 @@ case 'h': { std::cout << "Usage: osmcoastline_segments [OPTIONS] SEGFILE1 SEGFILE2\n"; print_help(); - std::exit(return_code_ok); + return return_code_ok; } case 'V': std::cout << "osmcoastline_segments " << get_osmcoastline_long_version() << " / " << get_libosmium_version() << '\n' - << "Copyright (C) 2012-2021 Jochen Topf \n" + << "Copyright (C) 2012-2022 Jochen Topf \n" << "License: GNU GENERAL PUBLIC LICENSE Version 3 .\n" << "This is free software: you are free to change and redistribute it.\n" << "There is NO WARRANTY, to the extent permitted by law.\n"; - std::exit(return_code_ok); + return return_code_ok; default: break; } @@ -159,18 +159,18 @@ if (optind != argc - 2) { std::cerr << "Usage: " << argv[0] << " [OPTIONS] SEGFILE1 SEGFILE2\n"; - std::exit(return_code_cmdline); + return return_code_cmdline; } try { segvec removed_segments; segvec added_segments; - InputFile file1{argv[optind]}; - InputFile file2{argv[optind + 1]}; + const InputFile file1{argv[optind]}; + const InputFile file2{argv[optind + 1]}; - osmium::util::TypedMemoryMapping m1{file1.size() / sizeof(osmium::UndirectedSegment), osmium::util::MemoryMapping::mapping_mode::readonly, file1.fd()}; - osmium::util::TypedMemoryMapping m2{file2.size() / sizeof(osmium::UndirectedSegment), osmium::util::MemoryMapping::mapping_mode::readonly, file2.fd()}; + const osmium::util::TypedMemoryMapping m1{file1.size() / sizeof(osmium::UndirectedSegment), osmium::util::MemoryMapping::mapping_mode::readonly, file1.fd()}; + const osmium::util::TypedMemoryMapping m2{file2.size() / sizeof(osmium::UndirectedSegment), osmium::util::MemoryMapping::mapping_mode::readonly, file2.fd()}; std::set_difference(m1.cbegin(), m1.cend(), m2.cbegin(), m2.cend(), std::back_inserter(removed_segments)); std::set_difference(m2.cbegin(), m2.cend(), m1.cbegin(), m1.cend(), std::back_inserter(added_segments)); @@ -192,7 +192,9 @@ return (removed_segments.empty() && added_segments.empty()) ? 0 : 1; } catch (const std::exception& e) { std::cerr << e.what() << '\n'; - std::exit(return_code_fatal); + return return_code_fatal; } + + return return_code_ok; } diff -Nru osmcoastline-2.3.1/src/osmcoastline_ways.cpp osmcoastline-2.4.0/src/osmcoastline_ways.cpp --- osmcoastline-2.3.1/src/osmcoastline_ways.cpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/osmcoastline_ways.cpp 2022-12-22 08:34:24.000000000 +0000 @@ -1,6 +1,6 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -109,22 +109,22 @@ if (argc >= 2) { if (!std::strcmp(argv[1], "--help") || !std::strcmp(argv[1], "-h")) { std::cout << "Usage: osmcoastline_ways OSMFILE [WAYSDB]\n"; - std::exit(return_code_ok); + return return_code_ok; } if (!std::strcmp(argv[1], "--version") || !std::strcmp(argv[1], "-V")) { std::cout << "osmcoastline_ways " << get_osmcoastline_long_version() << " / " << get_libosmium_version() << '\n' - << "Copyright (C) 2012-2021 Jochen Topf \n" + << "Copyright (C) 2012-2022 Jochen Topf \n" << "License: GNU GENERAL PUBLIC LICENSE Version 3 .\n" << "This is free software: you are free to change and redistribute it.\n" << "There is NO WARRANTY, to the extent permitted by law.\n"; - std::exit(return_code_ok); + return return_code_ok; } } if (argc != 2 && argc != 3) { std::cerr << "Usage: osmcoastline_ways OSMFILE [WAYSDB]\n"; - std::exit(return_code_cmdline); + return return_code_cmdline; } CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "OFF"); @@ -141,7 +141,7 @@ index_type index_neg; location_handler_type location_handler{index_pos, index_neg}; - osmium::io::File infile{input_osm_filename}; + const osmium::io::File infile{input_osm_filename}; osmium::io::Reader reader1{infile, osmium::osm_entity_bits::node}; osmium::apply(reader1, location_handler); reader1.close(); @@ -154,7 +154,9 @@ std::cerr << "Sum of way lengths: " << std::fixed << (coastline_ways_handler.sum_length() / 1000) << "km\n"; } catch (const std::exception& e) { std::cerr << e.what() << '\n'; - std::exit(return_code_fatal); + return return_code_fatal; } + + return return_code_ok; } diff -Nru osmcoastline-2.3.1/src/output_database.cpp osmcoastline-2.4.0/src/output_database.cpp --- osmcoastline-2.3.1/src/output_database.cpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/output_database.cpp 2022-12-22 08:34:24.000000000 +0000 @@ -1,6 +1,6 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -107,7 +107,7 @@ m_dataset.exec(sql.str()); } -void OutputDatabase::set_meta(int runtime, int memory_usage, const Stats& stats) { +void OutputDatabase::set_meta(std::time_t runtime, int memory_usage, const Stats& stats) { if (m_driver != "SQLite") { return; } @@ -158,7 +158,7 @@ feature.add_to_layer(); } -void OutputDatabase::add_ring(std::unique_ptr&& polygon, int osm_id, unsigned int nways, unsigned int npoints, bool fixed) { +void OutputDatabase::add_ring(std::unique_ptr&& polygon, osmium::object_id_type osm_id, unsigned int nways, unsigned int npoints, bool fixed) { m_srs.transform(polygon.get()); const bool land = polygon->getExteriorRing()->isClockwise(); @@ -176,19 +176,10 @@ hope that it will always be available. We use the GEOSisValidReason() function from the GEOS C interface to get to the reason. */ - -#if GDAL_VERSION_MAJOR == 1 && GDAL_VERSION_MINOR <= 10 - GEOSGeom p{polygon->exportToGEOS()}; - char* r = GEOSisValidReason(p); - std::string reason = r ? r : ""; - GEOSFree(r); - GEOSGeom_destroy(p); -#else GEOSContextHandle_t contextHandle = OGRGeometry::createGEOSContext(); char* r = GEOSisValidReason(polygon->exportToGEOS(contextHandle)); std::string reason = r ? r : ""; OGRGeometry::freeGEOSContext(contextHandle); -#endif if (!reason.empty()) { const std::size_t left_bracket = reason.find('['); @@ -199,9 +190,9 @@ double y = NAN; iss >> x; iss >> y; - reason = reason.substr(0, left_bracket); + reason.resize(left_bracket); - std::unique_ptr point{new OGRPoint()}; + auto point = std::make_unique(); point->assignSpatialReference(polygon->getSpatialReference()); point->setX(x); point->setY(y); @@ -216,7 +207,7 @@ } gdalcpp::Feature feature{m_layer_rings, std::move(polygon)}; - feature.set_field("osm_id", osm_id); + feature.set_field("osm_id", static_cast(osm_id)); feature.set_field("nways", static_cast(nways)); feature.set_field("npoints", static_cast(npoints)); feature.set_field("fixed", fixed); diff -Nru osmcoastline-2.3.1/src/output_database.hpp osmcoastline-2.4.0/src/output_database.hpp --- osmcoastline-2.3.1/src/output_database.hpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/output_database.hpp 2022-12-22 08:34:24.000000000 +0000 @@ -3,7 +3,7 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -89,13 +90,13 @@ void add_error_point(std::unique_ptr&& point, const char* error, osmium::object_id_type id = 0); void add_error_line(std::unique_ptr&& linestring, const char* error, osmium::object_id_type id = 0); - void add_ring(std::unique_ptr&& polygon, int osm_id, unsigned int nways, unsigned int npoints, bool fixed); + void add_ring(std::unique_ptr&& polygon, osmium::object_id_type osm_id, unsigned int nways, unsigned int npoints, bool fixed); void add_land_polygon(std::unique_ptr&& polygon); void add_water_polygon(std::unique_ptr&& polygon); void add_line(std::unique_ptr&& linestring); void set_options(const Options& options); - void set_meta(int runtime, int memory_usage, const Stats& stats); + void set_meta(std::time_t runtime, int memory_usage, const Stats& stats); void commit(); diff -Nru osmcoastline-2.3.1/src/return_codes.hpp osmcoastline-2.4.0/src/return_codes.hpp --- osmcoastline-2.3.1/src/return_codes.hpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/return_codes.hpp 2022-12-22 08:34:24.000000000 +0000 @@ -3,7 +3,7 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. diff -Nru osmcoastline-2.3.1/src/srs.cpp osmcoastline-2.4.0/src/srs.cpp --- osmcoastline-2.3.1/src/srs.cpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/srs.cpp 2022-12-22 08:34:24.000000000 +0000 @@ -1,6 +1,6 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. diff -Nru osmcoastline-2.3.1/src/srs.hpp osmcoastline-2.4.0/src/srs.hpp --- osmcoastline-2.3.1/src/srs.hpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/srs.hpp 2022-12-22 08:34:24.000000000 +0000 @@ -3,7 +3,7 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. @@ -53,7 +53,7 @@ public: - TransformationException(OGRErr error_code) : + explicit TransformationException(OGRErr error_code) : runtime_error("SRS transformation failed - OGRErr=" + std::to_string(error_code)) { } diff -Nru osmcoastline-2.3.1/src/stats.hpp osmcoastline-2.4.0/src/stats.hpp --- osmcoastline-2.3.1/src/stats.hpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/stats.hpp 2022-12-22 08:34:24.000000000 +0000 @@ -3,7 +3,7 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. diff -Nru osmcoastline-2.3.1/src/util.hpp osmcoastline-2.4.0/src/util.hpp --- osmcoastline-2.3.1/src/util.hpp 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/src/util.hpp 2022-12-22 08:34:24.000000000 +0000 @@ -3,7 +3,7 @@ /* - Copyright 2012-2021 Jochen Topf . + Copyright 2012-2022 Jochen Topf . This file is part of OSMCoastline. diff -Nru osmcoastline-2.3.1/.ycm_extra_conf.py osmcoastline-2.4.0/.ycm_extra_conf.py --- osmcoastline-2.3.1/.ycm_extra_conf.py 2021-09-02 12:21:02.000000000 +0000 +++ osmcoastline-2.4.0/.ycm_extra_conf.py 2022-12-22 08:34:24.000000000 +0000 @@ -22,7 +22,7 @@ '-Wno-unused-parameter', '-Wno-unused-variable', -'-std=c++11', +'-std=c++14', # '-x' and 'c++' also required # use 'c' for C projects