This is an automated email from the git hooks/post-receive script. sebastic pushed a commit to branch master in repository osmcoastline.
commit 7db9ecb474a91c7939d54090b58ba65d2da8d025 Author: Bas Couwenberg <sebas...@xs4all.nl> Date: Fri Sep 16 20:39:50 2016 +0200 Imported Upstream version 2.1.4 --- .travis.yml | 144 ++++++++++++++++++++++++++++++++++++++ .ycm_extra_conf.py | 5 ++ CHANGELOG.md | 22 ++++-- CMakeLists.txt | 27 +++++-- README.md | 1 + src/CMakeLists.txt | 6 +- src/coastline_handlers.hpp | 17 ++--- src/coastline_polygons.cpp | 38 +++++----- src/coastline_polygons.hpp | 15 ++-- src/coastline_ring.cpp | 17 +++-- src/coastline_ring.hpp | 20 ++++-- src/coastline_ring_collection.cpp | 59 +++++++++------- src/coastline_ring_collection.hpp | 33 +++++---- src/options.cpp | 36 +++++----- src/options.hpp | 2 +- src/osmcoastline.cpp | 51 +++++++++----- src/osmcoastline_filter.cpp | 40 ++++++----- src/osmcoastline_segments.cpp | 46 +++++++----- src/osmcoastline_ways.cpp | 55 +++++++++------ src/output_database.cpp | 28 ++++---- src/output_database.hpp | 7 +- src/srs.cpp | 1 + src/srs.hpp | 5 +- taginfo.json | 2 +- 24 files changed, 466 insertions(+), 211 deletions(-) diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..988b9d0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,144 @@ +#----------------------------------------------------------------------------- +# +# Configuration for continuous integration service at travis-ci.org +# +#----------------------------------------------------------------------------- + +language: generic + +sudo: false + +#----------------------------------------------------------------------------- + +matrix: + include: + + # 1/ Linux Clang Builds + + - os: linux + compiler: linux-clang36-release + addons: + apt: + sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test', 'boost-latest'] + packages: ['clang-3.6', 'libboost1.55-all-dev', 'pandoc', 'libgdal1-dev', 'libgeos-dev', 'sqlite3'] + env: COMPILER='clang++-3.6' BUILD_TYPE='Release' + + - os: linux + compiler: linux-clang37-dev + addons: + apt: + sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test', 'boost-latest'] + packages: ['clang-3.6', 'libboost1.55-all-dev', 'pandoc', 'libgdal1-dev', 'libgeos-dev', 'sqlite3'] + env: COMPILER='clang++-3.6' BUILD_TYPE='Dev' + + + - os: linux + compiler: linux-clang38-release + addons: + apt: + sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test', 'boost-latest'] + packages: ['clang-3.8', 'libboost1.55-all-dev', 'pandoc', 'libgdal1-dev', 'libgeos-dev', 'sqlite3'] + env: COMPILER='clang++-3.8' BUILD_TYPE='Release' + + - os: linux + compiler: linux-clang38-dev + addons: + apt: + sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test', 'boost-latest'] + packages: ['clang-3.8', 'libboost1.55-all-dev', 'pandoc', 'libgdal1-dev', 'libgeos-dev', 'sqlite3'] + env: COMPILER='clang++-3.8' BUILD_TYPE='Dev' + + + # 2/ Linux GCC Builds + - os: linux + compiler: linux-gcc48-release + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'boost-latest'] + packages: ['g++-4.8', 'libboost1.55-all-dev', 'pandoc', 'libgdal1-dev', 'libgeos-dev', 'sqlite3'] + env: COMPILER='g++-4.8' COMPILER_FLAGS='-Wno-return-type' BUILD_TYPE='Release' + + - os: linux + compiler: linux-gcc48-dev + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'boost-latest'] + packages: ['g++-4.8', 'libboost1.55-all-dev', 'pandoc', 'libgdal1-dev', 'libgeos-dev', 'sqlite3'] + env: COMPILER='g++-4.8' COMPILER_FLAGS='-Wno-return-type' BUILD_TYPE='Dev' + + + - os: linux + compiler: linux-gcc49-release + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'boost-latest'] + packages: ['g++-4.9', 'libboost1.55-all-dev', 'pandoc', 'libgdal1-dev', 'libgeos-dev', 'sqlite3'] + env: COMPILER='g++-4.9' BUILD_TYPE='Release' + + - os: linux + compiler: linux-gcc49-dev + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'boost-latest'] + packages: ['g++-4.9', 'libboost1.55-all-dev', 'pandoc', 'libgdal1-dev', 'libgeos-dev', 'sqlite3'] + env: COMPILER='g++-4.9' BUILD_TYPE='Dev' + + + - os: linux + compiler: linux-gcc5-release + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'boost-latest'] + packages: ['g++-5', 'libboost1.55-all-dev', 'pandoc', 'libgdal1-dev', 'libgeos-dev', 'sqlite3'] + env: COMPILER='g++-5' BUILD_TYPE='Release' + + - os: linux + compiler: linux-gcc5-dev + addons: + apt: + sources: ['ubuntu-toolchain-r-test', 'boost-latest'] + packages: ['g++-5', 'libboost1.55-all-dev', 'pandoc', 'libgdal1-dev', 'libgeos-dev', 'sqlite3'] + env: COMPILER='g++-5' BUILD_TYPE='Dev' + + + # 3/ OSX Clang Builds + - os: osx + osx_image: xcode6.4 + compiler: xcode64-clang-release + env: COMPILER='clang++' BUILD_TYPE='Release' + + - os: osx + osx_image: xcode6.4 + compiler: xcode64-clang-dev + env: COMPILER='clang++' BUILD_TYPE='Dev' + + + - os: osx + osx_image: xcode7 + compiler: xcode7-clang-release + env: COMPILER='clang++' BUILD_TYPE='Release' + + - os: osx + osx_image: xcode7 + compiler: xcode7-clang-dev + env: COMPILER='clang++' BUILD_TYPE='Dev' + +#----------------------------------------------------------------------------- + +install: + - git clone --quiet --depth 1 https://github.com/osmcode/libosmium.git ../libosmium + - | + if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then + brew install cmake boost || true + fi + - cmake --version + +before_script: + - cd ${TRAVIS_BUILD_DIR} + - mkdir build && cd build + - CXX=${COMPILER} CXXFLAGS=${COMPILER_FLAGS} cmake -LA .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} + +script: + - make VERBOSE=1 && ctest --output-on-failure + +#----------------------------------------------------------------------------- diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py index fdc78cb..5eb37f5 100644 --- a/.ycm_extra_conf.py +++ b/.ycm_extra_conf.py @@ -29,6 +29,11 @@ flags = [ '-x', 'c++', +# workaround for https://github.com/Valloric/YouCompleteMe/issues/303 +# also see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=800618 +'-isystem', +'/usr/lib/ycmd/clang_includes/', + '-Iinclude', '-I%s/../libosmium/include' % basedir, '-I/usr/include/gdal', diff --git a/CHANGELOG.md b/CHANGELOG.md index aa6d6ba..eab7245 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,16 +13,27 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +## [2.1.4] - 2016-09-16 + +### Changed + +- Miscellaneous code cleanups. + +### Fixed + +- Windows build. + + ## [2.1.3] - 2016-03-30 ### Added -- Add verbose option to osmcoastline_filter. -- osmcoastline_filter now shows memory used in verbose mode. +- Add verbose option to `osmcoastline_filter`. +- `osmcoastline_filter` now shows memory used in verbose mode. ### Changed -- Optimized osmcoastline_filter program. +- Optimized `osmcoastline_filter` program. - Use more features from newest libosmium. ### Fixed @@ -44,7 +55,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Updated for newest libosmium version (2.5.2). - Uses gdalcpp.hpp from https://github.com/joto/gdalcpp instead of directly talking to GDAL/OGR. Makes this compatible with GDAL 2. -- Improved internal code using unique_ptr where possible. +- Improved internal code using `unique_ptr` where possible. ### Fixed @@ -77,7 +88,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Added man pages -[unreleased]: https://github.com/osmcode/osmium-tool/compare/v2.1.3...HEAD +[unreleased]: https://github.com/osmcode/osmium-tool/compare/v2.1.4...HEAD +[2.1.4]: https://github.com/osmcode/osmium-tool/compare/v2.1.3...v2.1.4 [2.1.3]: https://github.com/osmcode/osmium-tool/compare/v2.1.2...v2.1.3 [2.1.2]: https://github.com/osmcode/osmium-tool/compare/v2.1.1...v2.1.2 [2.1.1]: https://github.com/osmcode/osmium-tool/compare/v2.1.0...v2.1.1 diff --git a/CMakeLists.txt b/CMakeLists.txt index e03ecd3..d13a5e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,8 +9,6 @@ cmake_minimum_required(VERSION 2.8 FATAL_ERROR) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - #----------------------------------------------------------------------------- # @@ -22,7 +20,7 @@ project(osmcoastline) set(OSMCOASTLINE_VERSION_MAJOR 2) set(OSMCOASTLINE_VERSION_MINOR 1) -set(OSMCOASTLINE_VERSION_PATCH 3) +set(OSMCOASTLINE_VERSION_PATCH 4) set(OSMCOASTLINE_VERSION ${OSMCOASTLINE_VERSION_MAJOR}.${OSMCOASTLINE_VERSION_MINOR}.${OSMCOASTLINE_VERSION_PATCH}) @@ -31,6 +29,8 @@ add_definitions(-DOSMCOASTLINE_VERSION="${OSMCOASTLINE_VERSION}") set(AUTHOR "Jochen Topf <joc...@topf.org>") +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + #----------------------------------------------------------------------------- # @@ -48,7 +48,6 @@ if(MSVC) find_library(GETOPT_LIBRARY NAMES wingetopt) if(GETOPT_INCLUDE_DIR AND GETOPT_LIBRARY) include_directories(${GETOPT_INCLUDE_DIR}) - list(APPEND OSMIUM_LIBRARIES ${GETOPT_LIBRARY}) else() set(GETOPT_MISSING 1) endif() @@ -148,7 +147,7 @@ if(CPPCHECK) # cpp doesn't find system includes for some reason, suppress that report set(CPPCHECK_OPTIONS ${CPPCHECK_OPTIONS} --suppress=missingIncludeSystem) - file(GLOB ALL_CODE *.cpp) + file(GLOB ALL_CODE src/*.cpp) set(CPPCHECK_FILES ${ALL_CODE}) @@ -165,6 +164,23 @@ endif(CPPCHECK) #----------------------------------------------------------------------------- # +# Optional "iwyu" target to check headers +# http://include-what-you-use.org/ +# +#----------------------------------------------------------------------------- +find_program(IWYU_TOOL iwyu_tool.py) + +if(IWYU_TOOL) + message(STATUS "Looking for iwyu_tool.py - found") + add_custom_target(iwyu ${IWYU_TOOL} -p ${CMAKE_BINARY_DIR}) +else() + message(STATUS "Looking for iwyu_tool.py - not found") + message(STATUS " Make target iwyu not available") +endif() + + +#----------------------------------------------------------------------------- +# # Optional "man" target to generate man pages # #----------------------------------------------------------------------------- @@ -223,6 +239,7 @@ endif(PANDOC) #----------------------------------------------------------------------------- find_library(GEOS_C_LIBRARIES NAMES geos_c) +include_directories (SYSTEM ${GEOS_C_INCLUDE_DIR}) add_definitions(${OSMIUM_WARNING_OPTIONS}) diff --git a/README.md b/README.md index 081808a..e56b4e1 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ http://wiki.openstreetmap.org/wiki/OSMCoastline https://github.com/osmcode/osmcoastline +[![Build Status](https://secure.travis-ci.org/osmcode/osmcoastline.svg)](http://travis-ci.org/osmcode/osmcoastline) ## Prerequisites diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ce62288..f31d589 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,15 +7,15 @@ #----------------------------------------------------------------------------- add_executable(osmcoastline osmcoastline.cpp coastline_ring.cpp coastline_ring_collection.cpp coastline_polygons.cpp output_database.cpp srs.cpp options.cpp) -target_link_libraries(osmcoastline ${OSMIUM_IO_LIBRARIES} ${GDAL_LIBRARIES} ${GEOS_C_LIBRARIES}) +target_link_libraries(osmcoastline ${OSMIUM_IO_LIBRARIES} ${GDAL_LIBRARIES} ${GEOS_C_LIBRARIES} ${GETOPT_LIBRARY}) install(TARGETS osmcoastline DESTINATION bin) add_executable(osmcoastline_filter osmcoastline_filter.cpp) -target_link_libraries(osmcoastline_filter ${OSMIUM_IO_LIBRARIES}) +target_link_libraries(osmcoastline_filter ${OSMIUM_IO_LIBRARIES} ${GETOPT_LIBRARY}) install(TARGETS osmcoastline_filter DESTINATION bin) add_executable(osmcoastline_segments osmcoastline_segments.cpp srs.cpp) -target_link_libraries(osmcoastline_segments ${GDAL_LIBRARIES}) +target_link_libraries(osmcoastline_segments ${GDAL_LIBRARIES} ${GETOPT_LIBRARY}) install(TARGETS osmcoastline_segments DESTINATION bin) add_executable(osmcoastline_ways osmcoastline_ways.cpp return_codes.hpp) diff --git a/src/coastline_handlers.hpp b/src/coastline_handlers.hpp index 449b2d4..5dc962e 100644 --- a/src/coastline_handlers.hpp +++ b/src/coastline_handlers.hpp @@ -42,23 +42,21 @@ class CoastlineHandlerPass1 : public osmium::handler::Handler { public: - CoastlineHandlerPass1(CoastlineRingCollection& coastline_rings) : + explicit CoastlineHandlerPass1(CoastlineRingCollection& coastline_rings) : m_coastline_rings(coastline_rings) { } void way(const osmium::Way& way) { // We are only interested in ways tagged with natural=coastline. - const char* natural = way.tags().get_value_by_key("natural"); - if (natural && !strcmp(natural, "coastline")) { - const char* bogus = way.tags().get_value_by_key("coastline"); - if (bogus && !strcmp(bogus, "bogus")) { + if (way.tags().has_tag("natural", "coastline")) { + if (way.tags().has_tag("coastline", "bogus")) { return; // ignore bogus coastline in Antarctica } m_coastline_rings.add_way(way); } } -}; +}; // class CoastlineHandlerPass1 /** * Osmium handler for the second pass over the input file in which @@ -89,11 +87,10 @@ public: } void node(const osmium::Node& node) { - const char* natural = node.tags().get_value_by_key("natural"); - if (natural && !strcmp(natural, "coastline")) { + if (node.tags().has_tag("natural", "coastline")) { try { m_output.add_error_point(m_factory.create_point(node), "tagged_node", node.id()); - } catch (osmium::geometry_error&) { + } catch (const osmium::geometry_error&) { std::cerr << "Ignoring illegal geometry for node " << node.id() << ".\n"; } } @@ -104,6 +101,6 @@ public: } } -}; +}; // class CoastlineHandlerPass2 #endif // COASTLINE_HANDLERS_HPP diff --git a/src/coastline_polygons.cpp b/src/coastline_polygons.cpp index 255e7b8..59dce64 100644 --- a/src/coastline_polygons.cpp +++ b/src/coastline_polygons.cpp @@ -20,15 +20,15 @@ */ #include <cassert> -#include <cmath> #include <iostream> #include <vector> #include <ogr_geometry.h> +class OGRSpatialReference; + #include "coastline_polygons.hpp" #include "output_database.hpp" -#include "return_codes.hpp" #include "srs.hpp" #include "util.hpp" @@ -46,14 +46,14 @@ std::unique_ptr<OGRPolygon> CoastlinePolygons::create_rectangular_polygon(double // make sure we are inside the bounds for the output SRS e.Intersect(srs.max_extent()); - std::unique_ptr<OGRLinearRing> ring { new OGRLinearRing() }; + std::unique_ptr<OGRLinearRing> ring{new OGRLinearRing()}; 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<OGRPolygon> polygon { new OGRPolygon() }; + std::unique_ptr<OGRPolygon> polygon{new OGRPolygon()}; polygon->addRingDirectly(ring.release()); polygon->assignSpatialReference(srs.out()); @@ -95,7 +95,7 @@ void CoastlinePolygons::split_geometry(std::unique_ptr<OGRGeometry>&& geom, int } else { // wkbMultiPolygon const auto mp = static_cast_unique_ptr<OGRMultiPolygon>(std::move(geom)); while (mp->getNumGeometries() > 0) { - std::unique_ptr<OGRPolygon> polygon { static_cast<OGRPolygon*>(mp->getGeometryRef(0)) }; + std::unique_ptr<OGRPolygon> polygon{static_cast<OGRPolygon*>(mp->getGeometryRef(0))}; mp->removeGeometry(0, false); polygon->assignSpatialReference(srs.out()); split_polygon(std::move(polygon), level); @@ -108,7 +108,7 @@ void CoastlinePolygons::split_polygon(std::unique_ptr<OGRPolygon>&& polygon, int m_max_split_depth = level; } - int num_points = polygon->getExteriorRing()->getNumPoints(); + const int num_points = polygon->getExteriorRing()->getNumPoints(); 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)); @@ -139,7 +139,7 @@ void CoastlinePolygons::split_polygon(std::unique_ptr<OGRPolygon>&& polygon, int } // split vertically - double MidY = (envelope.MaxY+envelope.MinY) / 2; + const double MidY = (envelope.MaxY+envelope.MinY) / 2; 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); @@ -151,15 +151,15 @@ void CoastlinePolygons::split_polygon(std::unique_ptr<OGRPolygon>&& polygon, int } // split horizontally - double MidX = (envelope.MaxX+envelope.MinX) / 2; + const double MidX = (envelope.MaxX+envelope.MinX) / 2; 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<OGRGeometry> geom1 { polygon->Intersection(b1.get()) }; - std::unique_ptr<OGRGeometry> geom2 { polygon->Intersection(b2.get()) }; + std::unique_ptr<OGRGeometry> geom1{polygon->Intersection(b1.get())}; + std::unique_ptr<OGRGeometry> geom2{polygon->Intersection(b2.get())}; if (geom1 && (geom1->getGeometryType() == wkbPolygon || geom1->getGeometryType() == wkbMultiPolygon) && geom2 && (geom2->getGeometryType() == wkbPolygon || geom2->getGeometryType() == wkbMultiPolygon)) { @@ -247,12 +247,12 @@ void CoastlinePolygons::add_line_to_output(std::unique_ptr<OGRLineString> line, // Add a coastline ring as LineString to output. Segments in this line that are // near the southern edge of the map or near the antimeridian are suppressed. void CoastlinePolygons::output_polygon_ring_as_lines(int max_points, const OGRLinearRing* ring) const { - int num = ring->getNumPoints(); + const int num = ring->getNumPoints(); assert(num > 2); - std::unique_ptr<OGRPoint> point1 { new OGRPoint }; - std::unique_ptr<OGRPoint> point2 { new OGRPoint }; - std::unique_ptr<OGRLineString> line { new OGRLineString }; + std::unique_ptr<OGRPoint> point1{new OGRPoint}; + std::unique_ptr<OGRPoint> point2{new OGRPoint}; + std::unique_ptr<OGRLineString> line{new OGRLineString}; ring->getPoint(0, point1.get()); for (int i=1; i < num; ++i) { @@ -262,7 +262,7 @@ void CoastlinePolygons::output_polygon_ring_as_lines(int max_points, const OGRLi if (line->getNumPoints() >= max_points || !added) { if (line->getNumPoints() >= 2) { - std::unique_ptr<OGRLineString> new_line { new OGRLineString }; + std::unique_ptr<OGRLineString> new_line{new OGRLineString}; using std::swap; swap(line, new_line); add_line_to_output(std::move(new_line), ring->getSpatialReference()); @@ -333,7 +333,7 @@ void CoastlinePolygons::split_bbox(OGREnvelope e, polygon_vector_type&& v) { if (e.MaxX - e.MinX < e.MaxY-e.MinY) { // split vertically - double MidY = (e.MaxY+e.MinY) / 2; + const double MidY = (e.MaxY+e.MinY) / 2; e1.MinX = e.MinX; e1.MinY = e.MinY; @@ -347,7 +347,7 @@ void CoastlinePolygons::split_bbox(OGREnvelope e, polygon_vector_type&& v) { } else { // split horizontally - double MidX = (e.MaxX+e.MinX) / 2; + const double MidX = (e.MaxX+e.MinX) / 2; e1.MinX = e.MinX; e1.MinY = e.MinY; @@ -371,8 +371,8 @@ void CoastlinePolygons::split_bbox(OGREnvelope e, polygon_vector_type&& v) { OGREnvelope e; polygon->getEnvelope(&e); - bool e1_intersects_e = e1.Intersects(e); - bool e2_intersects_e = e2.Intersects(e); + const bool e1_intersects_e = e1.Intersects(e); + const bool e2_intersects_e = e2.Intersects(e); if (e1_intersects_e && e2_intersects_e) { v1.emplace_back(static_cast<OGRPolygon*>(polygon->clone())); diff --git a/src/coastline_polygons.hpp b/src/coastline_polygons.hpp index 9296248..af97073 100644 --- a/src/coastline_polygons.hpp +++ b/src/coastline_polygons.hpp @@ -23,18 +23,15 @@ */ #include <memory> +#include <utility> #include <vector> -class OGRGeometry; -class OGRLinearRing; -class OGRLineString; -class OGRPoint; -class OGRPolygon; -class OGRMultiPolygon; -class OGREnvelope; +#include <ogr_geometry.h> + +class OGRSpatialReference; class OutputDatabase; -typedef std::vector<std::unique_ptr<OGRPolygon>> polygon_vector_type; +using polygon_vector_type = std::vector<std::unique_ptr<OGRPolygon>>; /** * A collection of land polygons created out of coastlines. @@ -123,6 +120,6 @@ public: /// Write all coastlines to the output database (as lines). void output_lines(int max_points) const; -}; +}; // class CoastlinePolygons #endif // COASTLINE_POLYGONS_HPP diff --git a/src/coastline_ring.cpp b/src/coastline_ring.cpp index ef4057f..112c515 100644 --- a/src/coastline_ring.cpp +++ b/src/coastline_ring.cpp @@ -19,9 +19,14 @@ */ +#include <cassert> #include <iostream> +#include <utility> + +#include <ogr_geometry.h> #include <osmium/geom/ogr.hpp> +#include <osmium/osm/undirected_segment.hpp> #include "coastline_ring.hpp" @@ -90,7 +95,7 @@ void CoastlineRing::close_ring() { } void CoastlineRing::close_antarctica_ring(int epsg) { - double min = epsg == 4326 ? -90.0 : -85.0511288; + 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(-179.99999, double(lat))); @@ -110,7 +115,7 @@ void CoastlineRing::close_antarctica_ring(int epsg) { std::unique_ptr<OGRPolygon> CoastlineRing::ogr_polygon(osmium::geom::OGRFactory<>& geom_factory, bool reverse) const { geom_factory.polygon_start(); - size_t num_points = 0; + std::size_t num_points = 0; if (reverse) { num_points = geom_factory.fill_polygon(m_way_node_list.crbegin(), m_way_node_list.crend()); } else { @@ -121,7 +126,7 @@ std::unique_ptr<OGRPolygon> CoastlineRing::ogr_polygon(osmium::geom::OGRFactory< std::unique_ptr<OGRLineString> CoastlineRing::ogr_linestring(osmium::geom::OGRFactory<>& geom_factory, bool reverse) const { geom_factory.linestring_start(); - size_t num_points = 0; + std::size_t num_points = 0; if (reverse) { num_points = geom_factory.fill_linestring(m_way_node_list.crbegin(), m_way_node_list.crend()); } else { @@ -132,18 +137,18 @@ std::unique_ptr<OGRLineString> CoastlineRing::ogr_linestring(osmium::geom::OGRFa std::unique_ptr<OGRPoint> CoastlineRing::ogr_first_point() const { const osmium::NodeRef& node_ref = m_way_node_list.front(); - return std::unique_ptr<OGRPoint>(new OGRPoint(node_ref.lon(), node_ref.lat())); + return std::unique_ptr<OGRPoint>{new OGRPoint(node_ref.lon(), node_ref.lat())}; } std::unique_ptr<OGRPoint> CoastlineRing::ogr_last_point() const { const osmium::NodeRef& node_ref = m_way_node_list.back(); - return std::unique_ptr<OGRPoint>(new OGRPoint(node_ref.lon(), node_ref.lat())); + return std::unique_ptr<OGRPoint>{new OGRPoint(node_ref.lon(), node_ref.lat())}; } // Pythagoras doesn't work on a round earth but that is ok here, we only need a // rough measure anyway double CoastlineRing::distance_to_start_position(osmium::Location pos) const { - osmium::Location p = m_way_node_list.front().location(); + const osmium::Location p = m_way_node_list.front().location(); return (pos.lon() - p.lon()) * (pos.lon() - p.lon()) + (pos.lat() - p.lat()) * (pos.lat() - p.lat()); } diff --git a/src/coastline_ring.hpp b/src/coastline_ring.hpp index 48d7c86..3a503a9 100644 --- a/src/coastline_ring.hpp +++ b/src/coastline_ring.hpp @@ -22,6 +22,7 @@ */ +#include <cassert> #include <map> #include <memory> #include <ostream> @@ -35,7 +36,7 @@ class OGRPoint; class OGRLineString; class OGRPolygon; -typedef std::multimap<osmium::object_id_type, osmium::Location*> posmap_type; +using posmap_type = std::multimap<osmium::object_id_type, osmium::Location*>; /** * The CoastlineRing class models a (possibly unfinished) ring of @@ -88,7 +89,7 @@ public: /** * Create CoastlineRing from a way. */ - CoastlineRing(const osmium::Way& way) : + explicit CoastlineRing(const osmium::Way& way) : m_way_node_list(), m_ring_id(way.id()), m_nways(1), @@ -108,26 +109,30 @@ public: /// ID of first node in the ring. osmium::object_id_type first_node_id() const { + assert(!m_way_node_list.empty()); return m_way_node_list.front().ref(); } /// ID of last node in the ring. osmium::object_id_type last_node_id() const { + assert(!m_way_node_list.empty()); return m_way_node_list.back().ref(); } /// Position of the first node in the ring. osmium::Location first_position() const { + assert(!m_way_node_list.empty()); return m_way_node_list.front().location(); } /// Position of the last node in the ring. osmium::Location last_position() const { + assert(!m_way_node_list.empty()); return m_way_node_list.back().location(); } /// Return ID of this ring (defined as smallest ID of the ways making up the ring). - osmium::object_id_type ring_id() const { + osmium::object_id_type ring_id() const noexcept { return m_ring_id; } @@ -135,14 +140,14 @@ public: * Set ring ID. The ring will only get the new ID if it is smaller than the * old one. */ - void update_ring_id(osmium::object_id_type new_id) { + void update_ring_id(osmium::object_id_type new_id) noexcept { if (new_id < m_ring_id) { m_ring_id = new_id; } } /// Returns the number of ways making up this ring. - unsigned int nways() const { + unsigned int nways() const noexcept { return m_nways; } @@ -157,7 +162,7 @@ public: } /// Was this ring fixed because of missing/wrong OSM data? - bool is_fixed() const { + bool is_fixed() const noexcept { return m_fixed; } @@ -170,6 +175,7 @@ public: * method does this. */ void fake_close() { + assert(!m_way_node_list.empty()); m_way_node_list.back().set_ref(first_node_id()); } @@ -258,7 +264,7 @@ public: friend std::ostream& operator<<(std::ostream& out, const CoastlineRing& cp); -}; +}; // class CoastlineRing inline bool operator<(const CoastlineRing& lhs, const CoastlineRing& rhs) { return lhs.first_position() < rhs.first_position(); diff --git a/src/coastline_ring_collection.cpp b/src/coastline_ring_collection.cpp index 56b0c43..b498c27 100644 --- a/src/coastline_ring_collection.cpp +++ b/src/coastline_ring_collection.cpp @@ -29,6 +29,12 @@ #include "output_database.hpp" #include "srs.hpp" +#ifdef _MSC_VER +#include <io.h> +#include <BaseTsd.h> +typedef SSIZE_T ssize_t; +#endif + extern SRS srs; extern bool debug; @@ -77,7 +83,7 @@ void CoastlineRingCollection::add_partial_ring(const osmium::Way& way) { // way at the front. This means that the way together with the // ring at front and the ring at back are now a complete ring. if (mnext != m_start_nodes.end()) { - coastline_rings_list_t::iterator next = mnext->second; + auto next = mnext->second; (*prev)->join(**next); m_start_nodes.erase(mnext); if ((*prev)->is_closed()) { @@ -99,7 +105,7 @@ void CoastlineRingCollection::add_partial_ring(const osmium::Way& way) { // We found a CoastlineRing where we can add the way at the front. if (mnext != m_start_nodes.end()) { - coastline_rings_list_t::iterator next = mnext->second; + auto next = mnext->second; (*next)->add_at_front(way); m_start_nodes.erase(mnext); if ((*next)->is_closed()) { @@ -145,7 +151,7 @@ std::vector<OGRGeometry*> CoastlineRingCollection::add_polygons_to_vector() { p->assignSpatialReference(srs.wgs84()); vector.push_back(p.release()); } else { - std::unique_ptr<OGRGeometry> geom { p->Buffer(0) }; + std::unique_ptr<OGRGeometry> geom{p->Buffer(0)}; if (is_valid_polygon(geom.get())) { geom->assignSpatialReference(srs.wgs84()); vector.push_back(geom.release()); @@ -194,21 +200,21 @@ osmium::Location intersection(const osmium::Segment& s1, const osmium::Segment&s return osmium::Location(); } - double denom = ((s2.second().lat() - s2.first().lat())*(s1.second().lon() - s1.first().lon())) - + const double denom = ((s2.second().lat() - s2.first().lat())*(s1.second().lon() - s1.first().lon())) - ((s2.second().lon() - s2.first().lon())*(s1.second().lat() - s1.first().lat())); if (denom != 0) { - double nume_a = ((s2.second().lon() - s2.first().lon())*(s1.first().lat() - s2.first().lat())) - - ((s2.second().lat() - s2.first().lat())*(s1.first().lon() - s2.first().lon())); + const double nume_a = ((s2.second().lon() - s2.first().lon())*(s1.first().lat() - s2.first().lat())) - + ((s2.second().lat() - s2.first().lat())*(s1.first().lon() - s2.first().lon())); - double nume_b = ((s1.second().lon() - s1.first().lon())*(s1.first().lat() - s2.first().lat())) - - ((s1.second().lat() - s1.first().lat())*(s1.first().lon() - s2.first().lon())); + const double nume_b = ((s1.second().lon() - s1.first().lon())*(s1.first().lat() - s2.first().lat())) - + ((s1.second().lat() - s1.first().lat())*(s1.first().lon() - s2.first().lon())); if ((denom > 0 && nume_a >= 0 && nume_a <= denom && nume_b >= 0 && nume_b <= denom) || (denom < 0 && nume_a <= 0 && nume_a >= denom && nume_b <= 0 && nume_b >= denom)) { - double ua = nume_a / denom; - double ix = s1.first().lon() + ua*(s1.second().lon() - s1.first().lon()); - double iy = s1.first().lat() + ua*(s1.second().lat() - s1.first().lat()); + const double ua = nume_a / denom; + const double ix = s1.first().lon() + ua*(s1.second().lon() - s1.first().lon()); + const double iy = s1.first().lat() + ua*(s1.second().lat() - s1.first().lat()); return osmium::Location(ix, iy); } } @@ -224,10 +230,10 @@ bool outside_x_range(const osmium::UndirectedSegment& s1, const osmium::Undirect } bool y_range_overlap(const osmium::UndirectedSegment& s1, const osmium::UndirectedSegment& s2) { - int tmin = s1.first().y() < s1.second().y() ? s1.first().y( ) : s1.second().y(); - int tmax = s1.first().y() < s1.second().y() ? s1.second().y() : s1.first().y(); - int omin = s2.first().y() < s2.second().y() ? s2.first().y() : s2.second().y(); - int omax = s2.first().y() < s2.second().y() ? s2.second().y() : s2.first().y(); + const int tmin = s1.first().y() < s1.second().y() ? s1.first().y( ) : s1.second().y(); + const int tmax = s1.first().y() < s1.second().y() ? s1.second().y() : s1.first().y(); + 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(); if (tmin > omax || omin > tmax) { return false; } @@ -235,7 +241,7 @@ bool y_range_overlap(const osmium::UndirectedSegment& s1, const osmium::Undirect } std::unique_ptr<OGRLineString> create_ogr_linestring(const osmium::Segment& segment) { - std::unique_ptr<OGRLineString> line { new OGRLineString }; + std::unique_ptr<OGRLineString> line{new OGRLineString}; line->setNumPoints(2); line->setPoint(0, segment.first().lon(), segment.first().lat()); line->setPoint(1, segment.second().lon(), segment.second().lat()); @@ -263,8 +269,12 @@ unsigned int CoastlineRingCollection::check_for_intersections(OutputDatabase& ou if (segments_fd >= 0) { if (debug) std::cerr << "Writing segments to file...\n"; ssize_t length = segments.size() * sizeof(osmium::UndirectedSegment); +#ifndef _MSC_VER if (::write(segments_fd, segments.data(), length) != length) { - throw std::runtime_error("Write error"); +#else + if (_write(segments_fd, segments.data(), length) != length) { +#endif + throw std::runtime_error{"Write error"}; } } @@ -293,7 +303,7 @@ unsigned int CoastlineRingCollection::check_for_intersections(OutputDatabase& ou } for (const auto& intersection : intersections) { - std::unique_ptr<OGRPoint> point { new OGRPoint(intersection.lon(), intersection.lat()) }; + std::unique_ptr<OGRPoint> point{new OGRPoint(intersection.lon(), intersection.lat())}; output.add_error_point(std::move(point), "intersection"); } @@ -302,8 +312,8 @@ unsigned int CoastlineRingCollection::check_for_intersections(OutputDatabase& ou bool CoastlineRingCollection::close_antarctica_ring(int epsg) { for (const auto& ring : m_list) { - osmium::Location fpos = ring->first_position(); - osmium::Location lpos = ring->last_position(); + const osmium::Location fpos = ring->first_position(); + const osmium::Location lpos = ring->last_position(); if (fpos.lon() > 179.99 && lpos.lon() < -179.99 && fpos.lat() < -77.0 && fpos.lat() > -78.0 && lpos.lat() < -77.0 && lpos.lat() > -78.0) { @@ -323,7 +333,7 @@ void CoastlineRingCollection::close_rings(OutputDatabase& output, bool debug, do // Create vector with all possible combinations of connections between rings. for (idmap_type::iterator eit = m_end_nodes.begin(); eit != m_end_nodes.end(); ++eit) { for (idmap_type::iterator sit = m_start_nodes.begin(); sit != m_start_nodes.end(); ++sit) { - double distance = (*sit->second)->distance_to_start_position((*eit->second)->last_position()); + const double distance = (*sit->second)->distance_to_start_position((*eit->second)->last_position()); if (distance < max_distance) { connections.emplace_back(distance, eit->first, sit->first); } @@ -359,7 +369,7 @@ void CoastlineRingCollection::close_rings(OutputDatabase& output, bool debug, do output.add_error_point(s->ogr_first_point(), "fixed_end_point", s->first_node_id()); if (e->last_position() != s->first_position()) { - std::unique_ptr<OGRLineString> linestring { new OGRLineString }; + std::unique_ptr<OGRLineString> linestring{new OGRLineString}; linestring->addPoint(e->last_position().lon(), e->last_position().lat()); linestring->addPoint(s->first_position().lon(), s->first_position().lat()); output.add_error_line(std::move(linestring), "added_line"); @@ -406,8 +416,7 @@ unsigned int CoastlineRingCollection::output_questionable(const CoastlinePolygon const unsigned int max_nodes_to_be_considered_questionable = 10000; unsigned int warnings = 0; - typedef std::pair<osmium::Location, CoastlineRing*> pos_ring_ptr_t; - std::vector<pos_ring_ptr_t> rings; + std::vector<std::pair<osmium::Location, CoastlineRing*>> rings; rings.reserve(m_list.size()); // put all rings in a vector... @@ -422,7 +431,7 @@ unsigned int CoastlineRingCollection::output_questionable(const CoastlinePolygon for (const auto& polygon : polygons) { const OGRLinearRing* exterior_ring = polygon->getExteriorRing(); osmium::Location pos(exterior_ring->getX(0), exterior_ring->getY(0)); - std::vector<pos_ring_ptr_t>::iterator rings_it = lower_bound(rings.begin(), rings.end(), std::make_pair<osmium::Location, CoastlineRing*>(std::move(pos), nullptr)); + auto rings_it = lower_bound(rings.begin(), rings.end(), std::make_pair<osmium::Location, CoastlineRing*>(std::move(pos), nullptr)); if (rings_it != rings.end()) { rings_it->second->set_outer(); } diff --git a/src/coastline_ring_collection.hpp b/src/coastline_ring_collection.hpp index bef8eb1..9feb640 100644 --- a/src/coastline_ring_collection.hpp +++ b/src/coastline_ring_collection.hpp @@ -22,6 +22,7 @@ */ +#include <cstddef> #include <list> #include <map> #include <memory> @@ -29,16 +30,16 @@ #include <osmium/geom/ogr.hpp> #include <osmium/osm/way.hpp> +#include <osmium/osm/types.hpp> #include "coastline_ring.hpp" class OGRGeometry; -class OGRPolygon; class OutputDatabase; class CoastlinePolygons; -typedef std::list<std::shared_ptr<CoastlineRing>> coastline_rings_list_t; -typedef std::map<osmium::object_id_type, coastline_rings_list_t::iterator> idmap_type; +using coastline_rings_list_t = std::list<std::shared_ptr<CoastlineRing>>; +using idmap_type = std::map<osmium::object_id_type, coastline_rings_list_t::iterator>; /** * A collection of CoastlineRing objects. Keeps a list of all start and end @@ -62,12 +63,12 @@ class CoastlineRingCollection { public: - typedef coastline_rings_list_t::const_iterator const_iterator; + using const_iterator = coastline_rings_list_t::const_iterator; CoastlineRingCollection(); /// Return the number of CoastlineRings in the collection. - size_t size() const { + std::size_t size() const noexcept { return m_list.size(); } @@ -85,19 +86,19 @@ public: } } - unsigned int num_ways() const { + unsigned int num_ways() const noexcept { return m_ways; } - unsigned int num_rings_from_single_way() const { + unsigned int num_rings_from_single_way() const noexcept { return m_rings_from_single_way; } - unsigned int num_unconnected_nodes() const { + unsigned int num_unconnected_nodes() const noexcept { return m_start_nodes.size() + m_end_nodes.size(); } - unsigned int num_fixed_rings() const { + unsigned int num_fixed_rings() const noexcept { return m_fixed_rings; } @@ -125,23 +126,27 @@ private: osmium::object_id_type start_id; osmium::object_id_type end_id; - Connection(double d, osmium::object_id_type s, osmium::object_id_type e) : distance(d), start_id(s), end_id(e) { } + Connection(double d, osmium::object_id_type s, osmium::object_id_type e) : + distance(d), + start_id(s), + end_id(e) { + } /** * Returns true if start or end ID of this connection is the same as the * other connections start or end ID. Used as predicate in std::remove_if(). */ - bool operator()(const Connection& other) { + bool operator()(const Connection& other) const noexcept { return start_id == other.start_id || end_id == other.end_id; } // Used in std::sort - static bool sort_by_distance(const Connection& a, const Connection& b) { + static bool sort_by_distance(const Connection& a, const Connection& b) noexcept { return a.distance > b.distance; } - }; + }; // struct Connection -}; +}; // class CoastlineRingCollection #endif // COASTLINE_RING_COLLECTION_HPP diff --git a/src/options.cpp b/src/options.cpp index fd51edd..a88ba29 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -28,6 +28,10 @@ #include "return_codes.hpp" #include "options.hpp" +#ifdef _MSC_VER +#define strcasecmp _stricmp +#endif + Options::Options(int argc, char* argv[]) : inputfile(), bbox_overlap(-1), @@ -90,7 +94,7 @@ Options::Options(int argc, char* argv[]) : break; case 'h': print_help(); - exit(return_code_ok); + std::exit(return_code_ok); case 'l': output_lines = true; break; @@ -101,17 +105,17 @@ Options::Options(int argc, char* argv[]) : } break; case 'p': - if (!strcmp(optarg, "none")) { + if (!std::strcmp(optarg, "none")) { output_polygons = output_polygon_type::none; - } else if (!strcmp(optarg, "land")) { + } else if (!std::strcmp(optarg, "land")) { output_polygons = output_polygon_type::land; - } else if (!strcmp(optarg, "water")) { + } else if (!std::strcmp(optarg, "water")) { output_polygons = output_polygon_type::water; - } else if (!strcmp(optarg, "both")) { + } else if (!std::strcmp(optarg, "both")) { output_polygons = output_polygon_type::both; } else { std::cerr << "Unknown argument '" << optarg << "' for -p/--output-polygon option\n"; - exit(return_code_cmdline); + std::exit(return_code_cmdline); } break; case 'o': @@ -138,25 +142,25 @@ Options::Options(int argc, char* argv[]) : << "License: GNU GENERAL PUBLIC LICENSE Version 3 <http://gnu.org/licenses/gpl.html>.\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"; - exit(return_code_ok); + std::exit(return_code_ok); default: - exit(return_code_cmdline); + std::exit(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"; - exit(return_code_cmdline); + std::exit(return_code_cmdline); } if (optind != argc - 1) { std::cerr << "Usage: " << argv[0] << " [OPTIONS] OSMFILE\n"; - exit(return_code_cmdline); + std::exit(return_code_cmdline); } if (output_database.empty()) { std::cerr << "Missing --output-database/-o option.\n"; - exit(return_code_cmdline); + std::exit(return_code_cmdline); } if (bbox_overlap == -1) { @@ -171,18 +175,18 @@ Options::Options(int argc, char* argv[]) : } int Options::get_epsg(const char* text) { - if (!strcasecmp(text, "WGS84") || !strcmp(text, "4326")) { + if (!strcasecmp(text, "WGS84") || !std::strcmp(text, "4326")) { return 4326; } - if (!strcmp(text, "3857")) { + if (!std::strcmp(text, "3857")) { return 3857; } - if (!strcmp(text, "3785") || !strcmp(text, "900913")) { + if (!std::strcmp(text, "3785") || !std::strcmp(text, "900913")) { std::cerr << "Please use code 3857 for the 'Google Mercator' projection!\n"; - exit(return_code_cmdline); + std::exit(return_code_cmdline); } std::cerr << "Unknown SRS '" << text << "'. Currently only 4326 (WGS84) and 3857 ('Google Mercator') are supported.\n"; - exit(return_code_cmdline); + std::exit(return_code_cmdline); } void Options::print_help() const { diff --git a/src/options.hpp b/src/options.hpp index 57e04dc..ada53af 100644 --- a/src/options.hpp +++ b/src/options.hpp @@ -108,6 +108,6 @@ private: void print_help() const; -}; +}; // class Options #endif // OPTIONS_HPP diff --git a/src/osmcoastline.cpp b/src/osmcoastline.cpp index 1ede948..f291983 100644 --- a/src/osmcoastline.cpp +++ b/src/osmcoastline.cpp @@ -19,18 +19,35 @@ */ -#include <fstream> -#include <list> -#include <time.h> -#include <unistd.h> +#include <cassert> +#include <cerrno> +#include <cstdlib> +#include <cstring> +#include <iostream> +#include <memory> +#include <sstream> +#include <stdexcept> +#include <string> +#include <utility> +#include <vector> + +#ifndef _MSC_VER +# include <unistd.h> +#else +# include <io.h> +#endif + +#include <ogr_core.h> +#include <ogr_geometry.h> #include <osmium/io/any_input.hpp> +#include <osmium/io/file.hpp> +#include <osmium/osm/entity_bits.hpp> #include <osmium/util/memory.hpp> #include <osmium/util/verbose_output.hpp> #include <osmium/visitor.hpp> #include "return_codes.hpp" -#include "coastline_ring.hpp" #include "coastline_ring_collection.hpp" #include "coastline_polygons.hpp" #include "output_database.hpp" @@ -70,7 +87,7 @@ polygon_vector_type create_polygons(CoastlineRingCollection& coastline_rings, Ou } if (mega_geometry->getGeometryType() != wkbMultiPolygon) { - throw std::runtime_error("mega geometry isn't a multipolygon. Something is very wrong!"); + throw std::runtime_error{"mega geometry isn't a multipolygon. Something is very wrong!"}; } OGRMultiPolygon* mega_multipolygon = static_cast<OGRMultiPolygon*>(mega_geometry.release()); @@ -79,7 +96,7 @@ polygon_vector_type create_polygons(CoastlineRingCollection& coastline_rings, Ou for (int i=0; i < mega_multipolygon->getNumGeometries(); ++i) { OGRGeometry* geom = mega_multipolygon->getGeometryRef(i); assert(geom->getGeometryType() == wkbPolygon); - std::unique_ptr<OGRPolygon> p { static_cast<OGRPolygon*>(geom) }; + std::unique_ptr<OGRPolygon> p{static_cast<OGRPolygon*>(geom)}; if (p->IsValid()) { polygons.push_back(std::move(p)); } else { @@ -134,7 +151,7 @@ int main(int argc, char *argv[]) { 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"; - exit(return_code_fatal); + std::exit(return_code_fatal); } // Optionally set up segments file @@ -143,8 +160,8 @@ int main(int argc, char *argv[]) { vout << "Writing segments to file '" << options.segmentfile << "' (because you told me to with --write-segments/-S option).\n"; segments_fd = ::open(options.segmentfile.c_str(), O_WRONLY | O_CREAT, 0666); if (segments_fd == -1) { - std::cerr << "Couldn't open file '" << options.segmentfile << "' (" << strerror(errno) << ")\n"; - exit(return_code_fatal); + std::cerr << "Couldn't open file '" << options.segmentfile << "' (" << std::strerror(errno) << ")\n"; + std::exit(return_code_fatal); } } @@ -159,7 +176,7 @@ int main(int argc, char *argv[]) { } else { vout << "Will NOT create geometry index (because you told me to using --no-index/-i).\n"; } - OutputDatabase output_database(options.output_database, srs, options.create_index); + OutputDatabase output_database{options.output_database, srs, options.create_index}; // The collection of all coastline rings we will be filling and then // operating on. @@ -169,11 +186,11 @@ int main(int argc, char *argv[]) { // This is in an extra scope so that the considerable amounts of memory // held by the handlers is recovered after we don't need them any more. vout << "Reading from file '" << options.inputfile << "'.\n"; - osmium::io::File infile(options.inputfile); + osmium::io::File infile{options.inputfile}; vout << "Reading ways (1st pass through input file)...\n"; - CoastlineHandlerPass1 handler_pass1(coastline_rings); - osmium::io::Reader reader1(infile, osmium::osm_entity_bits::way); + CoastlineHandlerPass1 handler_pass1{coastline_rings}; + osmium::io::Reader reader1{infile, osmium::osm_entity_bits::way}; osmium::apply(reader1, handler_pass1); reader1.close(); stats.ways = coastline_rings.num_ways(); @@ -187,8 +204,8 @@ int main(int argc, char *argv[]) { vout << memory_usage(); vout << "Reading nodes (2nd pass through input file)...\n"; - CoastlineHandlerPass2 handler_pass2(coastline_rings, output_database); - osmium::io::Reader reader2(infile, osmium::osm_entity_bits::node); + CoastlineHandlerPass2 handler_pass2{coastline_rings, output_database}; + osmium::io::Reader reader2{infile, osmium::osm_entity_bits::node}; osmium::apply(reader2, handler_pass2); reader2.close(); } @@ -197,7 +214,7 @@ int main(int argc, char *argv[]) { unsigned int missing_positions = coastline_rings.check_positions(options.debug); if (missing_positions) { vout << " There are " << missing_positions << " positions missing. Check that input file contains all nodes needed.\n"; - exit(return_code_error); + std::exit(return_code_error); } else { vout << " All positions are there.\n"; } diff --git a/src/osmcoastline_filter.cpp b/src/osmcoastline_filter.cpp index 1700769..a7d1d48 100644 --- a/src/osmcoastline_filter.cpp +++ b/src/osmcoastline_filter.cpp @@ -20,17 +20,25 @@ */ #include <algorithm> +#include <cstdlib> +#include <cstring> #include <getopt.h> #include <iostream> #include <string> #include <vector> #include <osmium/io/any_input.hpp> +#include <osmium/io/error.hpp> +#include <osmium/io/file.hpp> +#include <osmium/io/header.hpp> #include <osmium/io/input_iterator.hpp> #include <osmium/io/output_iterator.hpp> #include <osmium/io/pbf_output.hpp> -#include <osmium/handler.hpp> +#include <osmium/osm.hpp> +#include <osmium/osm/box.hpp> #include <osmium/osm/entity_bits.hpp> +#include <osmium/osm/node_ref.hpp> +#include <osmium/osm/types.hpp> #include <osmium/util/memory.hpp> #include <osmium/util/verbose_output.hpp> @@ -66,7 +74,7 @@ int main(int argc, char* argv[]) { switch (c) { case 'h': print_help(); - exit(return_code_ok); + std::exit(return_code_ok); case 'o': output_filename = optarg; break; @@ -79,9 +87,9 @@ int main(int argc, char* argv[]) { << "License: GNU GENERAL PUBLIC LICENSE Version 3 <http://gnu.org/licenses/gpl.html>.\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"; - exit(return_code_ok); + std::exit(return_code_ok); default: - exit(return_code_fatal); + std::exit(return_code_fatal); } } @@ -92,33 +100,32 @@ int main(int argc, char* argv[]) { if (output_filename.empty()) { std::cerr << "Missing -o/--output=OSMFILE option\n"; - exit(return_code_cmdline); + std::exit(return_code_cmdline); } if (optind != argc - 1) { std::cerr << "Usage: osmcoastline_filter [OPTIONS] OSMFILE\n"; - exit(return_code_cmdline); + std::exit(return_code_cmdline); } osmium::io::Header header; header.set("generator", "osmcoastline_filter"); - header.add_box(osmium::Box(-180.0, -90.0, 180.0, 90.0)); + header.add_box(osmium::Box{-180.0, -90.0, 180.0, 90.0}); - osmium::io::File infile(argv[optind]); + osmium::io::File infile{argv[optind]}; try { - osmium::io::Writer writer(output_filename, header); + osmium::io::Writer writer{output_filename, header}; auto output_it = osmium::io::make_output_iterator(writer); std::vector<osmium::object_id_type> ids; vout << "Reading ways (1st pass through input file)...\n"; { - osmium::io::Reader reader(infile, osmium::osm_entity_bits::way); + osmium::io::Reader reader{infile, osmium::osm_entity_bits::way}; auto ways = osmium::io::make_input_iterator_range<const osmium::Way>(reader); for (const osmium::Way& way : ways) { - const char* natural = way.get_value_by_key("natural"); - if (natural && !strcmp(natural, "coastline")) { + if (way.tags().has_tag("natural", "coastline")) { *output_it++ = way; for (const auto& nr : way.nodes()) { ids.push_back(nr.ref()); @@ -134,7 +141,7 @@ int main(int argc, char* argv[]) { vout << "Reading nodes (2nd pass through input file)...\n"; { - osmium::io::Reader reader(infile, osmium::osm_entity_bits::node); + osmium::io::Reader reader{infile, osmium::osm_entity_bits::node}; auto nodes = osmium::io::make_input_iterator_range<const osmium::Node>(reader); auto first = ids.begin(); @@ -150,17 +157,16 @@ int main(int argc, char* argv[]) { return true; } - const char* natural = node.get_value_by_key("natural"); - return natural && !strcmp(natural, "coastline"); + return node.tags().has_tag("natural", "coastline"); }); reader.close(); } writer.close(); - } catch (osmium::io_error& e) { + } catch (const osmium::io_error& e) { std::cerr << "io error: " << e.what() << "'\n"; - exit(return_code_fatal); + std::exit(return_code_fatal); } vout << "All done.\n"; diff --git a/src/osmcoastline_segments.cpp b/src/osmcoastline_segments.cpp index 9dd74c5..36522aa 100644 --- a/src/osmcoastline_segments.cpp +++ b/src/osmcoastline_segments.cpp @@ -20,17 +20,25 @@ */ #include <algorithm> -#include <cassert> +#include <cerrno> +#include <cstdlib> #include <fcntl.h> #include <getopt.h> #include <iostream> +#include <iterator> #include <memory> +#include <stdexcept> #include <string> #include <system_error> -#include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> -#include <unistd.h> +#include <vector> + +#ifndef _MSC_VER +# include <unistd.h> +#else +# include <io.h> +#endif #include <osmium/osm/undirected_segment.hpp> #include <osmium/util/memory_mapping.hpp> @@ -39,7 +47,7 @@ #include "return_codes.hpp" -typedef std::vector<osmium::UndirectedSegment> segvec; +using segvec = std::vector<osmium::UndirectedSegment>; class InputFile { @@ -48,11 +56,11 @@ class InputFile { public: - InputFile(const std::string& filename) : + explicit InputFile(const std::string& filename) : m_filename(filename), m_fd(::open(filename.c_str(), O_RDONLY)) { if (m_fd == -1) { - throw std::system_error(errno, std::system_category(), std::string("Opening '") + filename + "' failed"); + throw std::system_error{errno, std::system_category(), std::string{"Opening '"} + filename + "' failed"}; } } @@ -60,12 +68,12 @@ public: return m_fd; } - size_t size() const { + std::size_t size() const { struct stat s; if (::fstat(m_fd, &s) != 0) { - throw std::system_error(errno, std::system_category(), std::string("Can't get file size for '") + m_filename + "'"); + throw std::system_error{errno, std::system_category(), std::string{"Can't get file size for '"} + m_filename + "'"}; } - return size_t(s.st_size); + return std::size_t(s.st_size); } }; // class InputFile @@ -74,7 +82,7 @@ void print_help() { } void add_segment(gdalcpp::Layer& layer, int change, const osmium::UndirectedSegment& segment) { - auto linestring = std::unique_ptr<OGRLineString>(new OGRLineString()); + auto linestring = std::unique_ptr<OGRLineString>{new OGRLineString()}; linestring->addPoint(segment.first().lon(), segment.first().lat()); linestring->addPoint(segment.second().lon(), segment.second().lat()); @@ -133,7 +141,7 @@ int main(int argc, char *argv[]) { case 'h': { std::cout << "Usage: " << argv[0] << " [OPTIONS] SEGFILE1 SEGFILE2\n"; print_help(); - exit(return_code_ok); + std::exit(return_code_ok); } case 'V': std::cout << "osmcoastline_segments version " OSMCOASTLINE_VERSION "\n" @@ -141,7 +149,7 @@ int main(int argc, char *argv[]) { << "License: GNU GENERAL PUBLIC LICENSE Version 3 <http://gnu.org/licenses/gpl.html>.\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"; - exit(return_code_ok); + std::exit(return_code_ok); default: break; } @@ -149,24 +157,24 @@ int main(int argc, char *argv[]) { if (optind != argc - 2) { std::cerr << "Usage: " << argv[0] << " [OPTIONS] SEGFILE1 SEGFILE2\n"; - exit(return_code_cmdline); + std::exit(return_code_cmdline); } segvec removed_segments; segvec added_segments; try { - InputFile file1(argv[optind]); - InputFile file2(argv[optind+1]); + InputFile file1{argv[optind]}; + InputFile file2{argv[optind+1]}; - osmium::util::TypedMemoryMapping<osmium::UndirectedSegment> m1(file1.size() / sizeof(osmium::UndirectedSegment), osmium::util::MemoryMapping::mapping_mode::readonly, file1.fd()); - osmium::util::TypedMemoryMapping<osmium::UndirectedSegment> m2(file2.size() / sizeof(osmium::UndirectedSegment), osmium::util::MemoryMapping::mapping_mode::readonly, file2.fd()); + osmium::util::TypedMemoryMapping<osmium::UndirectedSegment> m1{file1.size() / sizeof(osmium::UndirectedSegment), osmium::util::MemoryMapping::mapping_mode::readonly, file1.fd()}; + osmium::util::TypedMemoryMapping<osmium::UndirectedSegment> 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)); - } catch (std::runtime_error& e) { + } catch (const std::runtime_error& e) { std::cerr << e.what() << "\n"; - exit(return_code_fatal); + std::exit(return_code_fatal); } if (dump) { diff --git a/src/osmcoastline_ways.cpp b/src/osmcoastline_ways.cpp index 09c8af4..6829ca7 100644 --- a/src/osmcoastline_ways.cpp +++ b/src/osmcoastline_ways.cpp @@ -19,24 +19,35 @@ */ +#include <cstdlib> #include <cstring> #include <iostream> #include <memory> #include <string> +#include <utility> #include <osmium/geom/haversine.hpp> #include <osmium/geom/ogr.hpp> +#include <osmium/handler.hpp> #include <osmium/handler/node_locations_for_ways.hpp> -#include <osmium/index/map/sparse_mem_array.hpp> +#include <osmium/index/map/sparse_mem_array.hpp> // IWYU pragma: keep #include <osmium/io/any_input.hpp> +#include <osmium/io/file.hpp> +#include <osmium/osm/entity_bits.hpp> +#include <osmium/osm/location.hpp> +#include <osmium/osm/way.hpp> +#include <osmium/osm/types.hpp> #include <osmium/visitor.hpp> +#include <ogr_core.h> +#include <ogr_geometry.h> + #include <gdalcpp.hpp> #include "return_codes.hpp" -typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_type; -typedef osmium::handler::NodeLocationsForWays<index_type, index_type> node_location_handler_type; +using index_type = osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location>; +using location_handler_type = osmium::handler::NodeLocationsForWays<index_type, index_type>; class CoastlineWaysHandler : public osmium::handler::Handler { @@ -49,7 +60,7 @@ class CoastlineWaysHandler : public osmium::handler::Handler { public: - CoastlineWaysHandler(const std::string& db_filename) : + explicit CoastlineWaysHandler(const std::string& db_filename) : m_length(0.0), m_dataset("SQLite", db_filename, gdalcpp::SRS{}, {"SPATIALITE=TRUE", "INIT_WITH_EPSG=no" }), m_layer_ways(m_dataset, "ways", wkbLineString) { @@ -65,7 +76,7 @@ public: m_layer_ways.commit_transaction(); } - void way(osmium::Way& way) { + void way(const osmium::Way& way) { m_length += osmium::geom::haversine::distance(way.nodes()); try { std::unique_ptr<OGRLineString> ogrlinestring = m_factory.create_linestring(way); @@ -74,25 +85,25 @@ public: feature.set_field("name", way.tags().get_value_by_key("name")); feature.set_field("source", way.tags().get_value_by_key("source")); - const char* coastline = way.tags().get_value_by_key("coastline"); - feature.set_field("bogus", (coastline && !std::strcmp(coastline, "bogus")) ? "t" : "f"); + const bool bogus = way.tags().has_tag("coastline", "bogus"); + feature.set_field("bogus", bogus ? "t" : "f"); feature.add_to_layer(); - } catch (osmium::geometry_error&) { + } catch (const osmium::geometry_error&) { std::cerr << "Ignoring illegal geometry for way " << way.id() << ".\n"; } } - double sum_length() const { + double sum_length() const noexcept { return m_length; } -}; +}; // class CoastlineWaysHandler int main(int argc, char* argv[]) { if (argc >= 2) { if (!std::strcmp(argv[1], "--help") || !std::strcmp(argv[1], "-h")) { std::cout << "Usage: osmcoastline_ways OSMFILE [WAYSDB]\n"; - exit(return_code_ok); + std::exit(return_code_ok); } if (!std::strcmp(argv[1], "--version") || !std::strcmp(argv[1], "-V")) { @@ -101,35 +112,35 @@ int main(int argc, char* argv[]) { << "License: GNU GENERAL PUBLIC LICENSE Version 3 <http://gnu.org/licenses/gpl.html>.\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"; - exit(return_code_ok); + std::exit(return_code_ok); } } if (argc != 2 && argc != 3) { std::cerr << "Usage: osmcoastline_ways OSMFILE [WAYSDB]\n"; - exit(return_code_cmdline); + std::exit(return_code_cmdline); } CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "OFF"); - std::string input_osm_filename { argv[1] }; - std::string output_db_filename { "coastline-ways.db" }; + const std::string input_osm_filename{argv[1]}; + std::string output_db_filename{"coastline-ways.db"}; if (argc >= 3) { output_db_filename = argv[2]; } - index_type store_pos; - index_type store_neg; - node_location_handler_type location_handler(store_pos, store_neg); + index_type index_pos; + index_type index_neg; + location_handler_type location_handler{index_pos, index_neg}; - osmium::io::File infile(input_osm_filename); - osmium::io::Reader reader1(infile, osmium::osm_entity_bits::node); + osmium::io::File infile{input_osm_filename}; + osmium::io::Reader reader1{infile, osmium::osm_entity_bits::node}; osmium::apply(reader1, location_handler); reader1.close(); - CoastlineWaysHandler coastline_ways_handler(output_db_filename); - osmium::io::Reader reader2(infile, osmium::osm_entity_bits::way); + CoastlineWaysHandler coastline_ways_handler{output_db_filename}; + osmium::io::Reader reader2{infile, osmium::osm_entity_bits::way}; osmium::apply(reader2, location_handler, coastline_ways_handler); reader2.close(); diff --git a/src/output_database.cpp b/src/output_database.cpp index 293da90..0f701c7 100644 --- a/src/output_database.cpp +++ b/src/output_database.cpp @@ -19,11 +19,15 @@ */ +#include <cstddef> #include <iostream> #include <sstream> +#include <utility> #include <gdal_version.h> #include <geos_c.h> +#include <ogr_core.h> +#include <ogr_geometry.h> #include "options.hpp" #include "output_database.hpp" @@ -83,7 +87,7 @@ void OutputDatabase::set_options(const Options& options) { sql << "INSERT INTO options (overlap, close_distance, max_points_in_polygons, split_large_polygons) VALUES (" << options.bbox_overlap << ", "; - if (options.close_distance==0) { + if (options.close_distance == 0) { sql << "NULL, "; } else { sql << options.close_distance << ", "; @@ -129,7 +133,7 @@ void OutputDatabase::commit() { void OutputDatabase::add_error_point(std::unique_ptr<OGRPoint>&& point, const char* error, osmium::object_id_type id) { m_srs.transform(point.get()); - gdalcpp::Feature feature(m_layer_error_points, std::move(point)); + gdalcpp::Feature feature{m_layer_error_points, std::move(point)}; feature.set_field("osm_id", std::to_string(id).c_str()); feature.set_field("error", error); feature.add_to_layer(); @@ -137,7 +141,7 @@ void OutputDatabase::add_error_point(std::unique_ptr<OGRPoint>&& point, const ch void OutputDatabase::add_error_line(std::unique_ptr<OGRLineString>&& linestring, const char* error, osmium::object_id_type id) { m_srs.transform(linestring.get()); - gdalcpp::Feature feature(m_layer_error_lines, std::move(linestring)); + gdalcpp::Feature feature{m_layer_error_lines, std::move(linestring)}; feature.set_field("osm_id", std::to_string(id).c_str()); feature.set_field("error", error); feature.add_to_layer(); @@ -146,8 +150,8 @@ void OutputDatabase::add_error_line(std::unique_ptr<OGRLineString>&& linestring, void OutputDatabase::add_ring(std::unique_ptr<OGRPolygon>&& polygon, int osm_id, int nways, int npoints, bool fixed) { m_srs.transform(polygon.get()); - bool land = polygon->getExteriorRing()->isClockwise(); - bool valid = polygon->IsValid(); + const bool land = polygon->getExteriorRing()->isClockwise(); + const bool valid = polygon->IsValid(); if (!valid) { /* @@ -176,8 +180,8 @@ void OutputDatabase::add_ring(std::unique_ptr<OGRPolygon>&& polygon, int osm_id, #endif if (!reason.empty()) { - size_t left_bracket = reason.find('['); - size_t right_bracket = reason.find(']'); + const std::size_t left_bracket = reason.find('['); + const std::size_t right_bracket = reason.find(']'); std::istringstream iss(reason.substr(left_bracket+1, right_bracket-left_bracket-1), std::istringstream::in); double x; @@ -186,7 +190,7 @@ void OutputDatabase::add_ring(std::unique_ptr<OGRPolygon>&& polygon, int osm_id, iss >> y; reason = reason.substr(0, left_bracket); - std::unique_ptr<OGRPoint> point { new OGRPoint() }; + std::unique_ptr<OGRPoint> point{new OGRPoint()}; point->assignSpatialReference(polygon->getSpatialReference()); point->setX(x); point->setY(y); @@ -200,7 +204,7 @@ void OutputDatabase::add_ring(std::unique_ptr<OGRPolygon>&& polygon, int osm_id, } } - gdalcpp::Feature feature(m_layer_rings, std::move(polygon)); + gdalcpp::Feature feature{m_layer_rings, std::move(polygon)}; feature.set_field("osm_id", osm_id); feature.set_field("nways", nways); feature.set_field("npoints", npoints); @@ -212,19 +216,19 @@ void OutputDatabase::add_ring(std::unique_ptr<OGRPolygon>&& polygon, int osm_id, void OutputDatabase::add_land_polygon(std::unique_ptr<OGRPolygon>&& polygon) { m_srs.transform(polygon.get()); - gdalcpp::Feature feature(m_layer_land_polygons, std::move(polygon)); + gdalcpp::Feature feature{m_layer_land_polygons, std::move(polygon)}; feature.add_to_layer(); } void OutputDatabase::add_water_polygon(std::unique_ptr<OGRPolygon>&& polygon) { m_srs.transform(polygon.get()); - gdalcpp::Feature feature(m_layer_water_polygons, std::move(polygon)); + gdalcpp::Feature feature{m_layer_water_polygons, std::move(polygon)}; feature.add_to_layer(); } void OutputDatabase::add_line(std::unique_ptr<OGRLineString>&& linestring) { m_srs.transform(linestring.get()); - gdalcpp::Feature feature(m_layer_lines, std::move(linestring)); + gdalcpp::Feature feature{m_layer_lines, std::move(linestring)}; feature.add_to_layer(); } diff --git a/src/output_database.hpp b/src/output_database.hpp index 4dac320..0c560cb 100644 --- a/src/output_database.hpp +++ b/src/output_database.hpp @@ -30,8 +30,11 @@ #include <gdalcpp.hpp> -class SRS; +class OGRLineString; +class OGRPoint; +class OGRPolygon; class Options; +class SRS; struct Stats; /** @@ -91,6 +94,6 @@ public: void commit(); -}; +}; // class OutputDatabase #endif // OUTPUT_DATABASE_HPP diff --git a/src/srs.cpp b/src/srs.cpp index 78a5809..a0c4ec3 100644 --- a/src/srs.cpp +++ b/src/srs.cpp @@ -19,6 +19,7 @@ */ +#include <ogr_core.h> #include <ogr_geometry.h> #include "srs.hpp" diff --git a/src/srs.hpp b/src/srs.hpp index 5ce32b7..3e27de6 100644 --- a/src/srs.hpp +++ b/src/srs.hpp @@ -63,6 +63,7 @@ public: OGRSpatialReference* wgs84() { return &m_srs_wgs84; } + OGRSpatialReference* out() { return &m_srs_out; } @@ -86,13 +87,15 @@ public: double max_x() const { return m_transform ? 20037500.0 : 179.9999; } + double min_x() const { return m_transform ? -20037500.0 : -179.9999; } + double min_y() const { return m_transform ? -20037400.0 : -85.049; } -}; +}; // class SRS #endif // SRS_HPP diff --git a/taginfo.json b/taginfo.json index 3360c60..b1ae356 100644 --- a/taginfo.json +++ b/taginfo.json @@ -6,7 +6,7 @@ "description": "Program that assembles continuous coastlines from OSM data and creates land and water polygons.", "project_url": "http://wiki.osm.org/wiki/OSMCoastline", "doc_url": "https://github.com/osmcode/osmcoastline", - "icon_url": "http://osmcode.org/img/logo-osmcoastline-16x16.png", + "icon_url": "http://osmcode.org/img/logo-osmcoastline.svg", "contact_name": "Jochen Topf", "contact_email": "joc...@topf.org", "keywords": [ -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/osmcoastline.git _______________________________________________ Pkg-grass-devel mailing list Pkg-grass-devel@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel