[osmcoastline] 05/06: Drop GDAL 2.0 patch, included upstream.

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Thu Jan 7 07:16:37 UTC 2016


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository osmcoastline.

commit 2550c8d1e4102295976ff8bc84def03fe8c175dd
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Thu Jan 7 07:43:45 2016 +0100

    Drop GDAL 2.0 patch, included upstream.
---
 debian/changelog                                   |    1 +
 ...h-to-gdalcpp.hpp.-Adds-support-for-GDAL-2.patch | 1726 --------------------
 debian/patches/series                              |    1 -
 3 files changed, 1 insertion(+), 1727 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 66e26f1..1f12c3d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,7 @@ osmcoastline (2.1.2-1) UNRELEASED; urgency=medium
 
   * New upstream release.
   * Update copyright years for Jochen Topf.
+  * Drop GDAL 2.0 patch, included upstream.
 
  -- Bas Couwenberg <sebastic at debian.org>  Thu, 07 Jan 2016 07:40:09 +0100
 
diff --git a/debian/patches/0001-Switch-to-gdalcpp.hpp.-Adds-support-for-GDAL-2.patch b/debian/patches/0001-Switch-to-gdalcpp.hpp.-Adds-support-for-GDAL-2.patch
deleted file mode 100644
index 3bca302..0000000
--- a/debian/patches/0001-Switch-to-gdalcpp.hpp.-Adds-support-for-GDAL-2.patch
+++ /dev/null
@@ -1,1726 +0,0 @@
-From 709baa96915d2e82b2fa99788d9476cbfdf17812 Mon Sep 17 00:00:00 2001
-From: Jochen Topf <jochen at topf.org>
-Date: Tue, 24 Nov 2015 21:37:06 +0100
-Subject: Switch to gdalcpp.hpp. Adds support for GDAL 2.
-Origin: https://github.com/osmcode/osmcoastline/commit/709baa96915d2e82b2fa99788d9476cbfdf17812
-Bug: https://github.com/osmcode/osmcoastline/issues/15
-Bug-Debian: https://bugs.debian.org/802813
-
-Also lots of unique_ptr goodness.
-
-Fixes #15.
-
---- a/.ycm_extra_conf.py
-+++ b/.ycm_extra_conf.py
-@@ -29,7 +29,7 @@ flags = [
- '-x',
- 'c++',
- 
--# libosmium include dirs
-+'-Iinclude',
- '-I%s/../libosmium/include' % basedir,
- '-I/usr/include/gdal',
- 
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -36,6 +36,8 @@ set(AUTHOR "Jochen Topf <jochen at topf.org
- #
- #-----------------------------------------------------------------------------
- 
-+include_directories(include)
-+
- find_package(Osmium COMPONENTS io gdal)
- include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
- 
---- /dev/null
-+++ b/include/gdalcpp.hpp
-@@ -0,0 +1,406 @@
-+#ifndef GDALCPP_HPP
-+#define GDALCPP_HPP
-+
-+/*
-+
-+C++11 wrapper classes for GDAL/OGR.
-+
-+Version 1.1.1
-+
-+https://github.com/joto/gdalcpp
-+
-+Copyright 2015 Jochen Topf <jochen at topf.org>
-+
-+Boost Software License - Version 1.0 - August 17th, 2003
-+
-+Permission is hereby granted, free of charge, to any person or organization
-+obtaining a copy of the software and accompanying documentation covered by
-+this license (the "Software") to use, reproduce, display, distribute,
-+execute, and transmit the Software, and to prepare derivative works of the
-+Software, and to permit third-parties to whom the Software is furnished to
-+do so, all subject to the following:
-+
-+The copyright notices in the Software and this entire statement, including
-+the above license grant, this restriction and the following disclaimer,
-+must be included in all copies of the Software, in whole or in part, and
-+all derivative works of the Software, unless such copies or derivative
-+works are solely in the form of machine-executable object code generated by
-+a source language processor.
-+
-+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-+DEALINGS IN THE SOFTWARE.
-+
-+*/
-+
-+#include <algorithm>
-+#include <memory>
-+#include <stdexcept>
-+#include <string>
-+#include <vector>
-+
-+#include <gdal_priv.h>
-+#include <gdal_version.h>
-+#include <ogr_api.h>
-+#include <ogrsf_frmts.h>
-+
-+namespace gdalcpp {
-+
-+#if GDAL_VERSION_MAJOR >= 2
-+    using gdal_driver_type = GDALDriver;
-+    using gdal_dataset_type = GDALDataset;
-+#else
-+    using gdal_driver_type = OGRSFDriver;
-+    using gdal_dataset_type = OGRDataSource;
-+#endif
-+
-+    /**
-+     * Exception thrown for all errors in this class.
-+     */
-+    class gdal_error : public std::runtime_error {
-+
-+        std::string m_driver;
-+        std::string m_dataset;
-+        std::string m_layer;
-+        std::string m_field;
-+        OGRErr m_error;
-+
-+    public:
-+
-+        gdal_error(const std::string& message,
-+                   OGRErr error,
-+                   const std::string& driver = "",
-+                   const std::string& dataset = "",
-+                   const std::string& layer = "",
-+                   const std::string& field = "") :
-+            std::runtime_error(message),
-+            m_driver(driver),
-+            m_dataset(dataset),
-+            m_layer(layer),
-+            m_field(field),
-+            m_error(error) {
-+        }
-+
-+        const std::string& driver() const {
-+            return m_driver;
-+        }
-+
-+        const std::string& dataset() const {
-+            return m_dataset;
-+        }
-+
-+        const std::string& layer() const {
-+            return m_layer;
-+        }
-+
-+        const std::string& field() const {
-+            return m_field;
-+        }
-+
-+        OGRErr error() const {
-+            return m_error;
-+        }
-+
-+    }; // class gdal_error
-+
-+    namespace detail {
-+
-+        struct init_wrapper {
-+            init_wrapper() { OGRRegisterAll(); }
-+            ~init_wrapper() { OGRCleanupAll(); }
-+        };
-+
-+        struct init_library {
-+            init_library() {
-+                static init_wrapper iw;
-+            }
-+        };
-+
-+        class Driver : private init_library {
-+
-+            gdal_driver_type* m_driver;
-+
-+        public:
-+
-+            Driver(const std::string& driver_name) :
-+                init_library(),
-+#if GDAL_VERSION_MAJOR >= 2
-+                m_driver(GetGDALDriverManager()->GetDriverByName(driver_name.c_str())) {
-+#else
-+                m_driver(OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str())) {
-+#endif
-+                if (!m_driver) {
-+                    throw gdal_error(std::string("unknown driver: '") + driver_name + "'", OGRERR_NONE, driver_name);
-+                }
-+            }
-+
-+            gdal_driver_type& get() const {
-+                return *m_driver;
-+            }
-+
-+        }; // struct Driver
-+
-+        struct Options {
-+
-+            std::vector<std::string> m_options;
-+            std::unique_ptr<const char*[]> m_ptrs;
-+
-+            Options(const std::vector<std::string>& options) :
-+                m_options(options),
-+                m_ptrs(new const char*[options.size()+1]) {
-+                std::transform(m_options.begin(), m_options.end(), m_ptrs.get(), [&](const std::string& s) {
-+                    return s.data();
-+                });
-+                m_ptrs[options.size()] = nullptr;
-+            }
-+
-+            char** get() const {
-+                return const_cast<char**>(m_ptrs.get());
-+            }
-+
-+        }; // struct Options
-+
-+    } // namespace detail
-+
-+    class SRS {
-+
-+        OGRSpatialReference m_spatial_reference;
-+
-+    public:
-+
-+        SRS() :
-+            m_spatial_reference() {
-+            auto result = m_spatial_reference.SetWellKnownGeogCS("WGS84");
-+            if (result != OGRERR_NONE) {
-+                throw gdal_error(std::string("can not initialize spatial reference system WGS84"), result);
-+            }
-+        }
-+
-+        explicit SRS(int epsg) :
-+            m_spatial_reference() {
-+            auto result = m_spatial_reference.importFromEPSG(epsg);
-+            if (result != OGRERR_NONE) {
-+                throw gdal_error(std::string("can not initialize spatial reference system for EPSG:") + std::to_string(epsg), result);
-+            }
-+        }
-+
-+        explicit SRS(const char* name) :
-+            m_spatial_reference() {
-+            auto result = m_spatial_reference.importFromProj4(name);
-+            if (result != OGRERR_NONE) {
-+                throw gdal_error(std::string("can not initialize spatial reference system '") + name + "'", result);
-+            }
-+        }
-+
-+        explicit SRS(const std::string& name) :
-+            m_spatial_reference() {
-+            auto result = m_spatial_reference.importFromProj4(name.c_str());
-+            if (result != OGRERR_NONE) {
-+                throw gdal_error(std::string("can not initialize spatial reference system '") + name + "'", result);
-+            }
-+        }
-+
-+        explicit SRS(const OGRSpatialReference& spatial_reference) :
-+            m_spatial_reference(spatial_reference) {
-+        }
-+
-+        OGRSpatialReference& get() {
-+            return m_spatial_reference;
-+        }
-+
-+        const OGRSpatialReference& get() const {
-+            return m_spatial_reference;
-+        }
-+
-+    }; // class SRS
-+
-+    class Dataset {
-+
-+        struct gdal_dataset_deleter {
-+
-+            void operator()(gdal_dataset_type* ds) {
-+#if GDAL_VERSION_MAJOR >= 2
-+                GDALClose(ds);
-+#else
-+                OGRDataSource::DestroyDataSource(ds);
-+#endif
-+            }
-+
-+        }; // struct gdal_dataset_deleter
-+
-+        std::string m_driver_name;
-+        std::string m_dataset_name;
-+        detail::Options m_options;
-+        SRS m_srs;
-+        std::unique_ptr<gdal_dataset_type, gdal_dataset_deleter> m_dataset;
-+
-+    public:
-+
-+        Dataset(const std::string& driver_name, const std::string& dataset_name, const SRS& srs = SRS{}, const std::vector<std::string>& options = {}) :
-+            m_driver_name(driver_name),
-+            m_dataset_name(dataset_name),
-+            m_options(options),
-+            m_srs(srs),
-+#if GDAL_VERSION_MAJOR >= 2
-+            m_dataset(detail::Driver(driver_name).get().Create(dataset_name.c_str(), 0, 0, 0, GDT_Unknown, m_options.get())) {
-+#else
-+            m_dataset(detail::Driver(driver_name).get().CreateDataSource(dataset_name.c_str(), m_options.get())) {
-+#endif
-+            if (!m_dataset) {
-+                throw gdal_error(std::string("failed to create dataset '") + dataset_name + "'", OGRERR_NONE, driver_name, dataset_name);
-+            }
-+        }
-+
-+        const std::string& driver_name() const {
-+            return m_driver_name;
-+        }
-+
-+        const std::string& dataset_name() const {
-+            return m_dataset_name;
-+        }
-+
-+        gdal_dataset_type& get() const {
-+            return *m_dataset;
-+        }
-+
-+        SRS& srs() {
-+            return m_srs;
-+        }
-+
-+        void exec(const char* sql) {
-+            auto result = m_dataset->ExecuteSQL(sql, nullptr, nullptr);
-+            if (result) {
-+                m_dataset->ReleaseResultSet(result);
-+            }
-+        }
-+
-+        void exec(const std::string& sql) {
-+            exec(sql.c_str());
-+        }
-+
-+
-+        Dataset& start_transaction() {
-+#if GDAL_VERSION_MAJOR >= 2
-+            m_dataset->StartTransaction();
-+#endif
-+            return *this;
-+        }
-+
-+        Dataset& commit_transaction() {
-+#if GDAL_VERSION_MAJOR >= 2
-+            m_dataset->CommitTransaction();
-+#endif
-+            return *this;
-+        }
-+
-+    }; // class Dataset
-+
-+    class Layer {
-+
-+        detail::Options m_options;
-+        Dataset& m_dataset;
-+        OGRLayer* m_layer;
-+
-+    public:
-+
-+        Layer(Dataset& dataset, const std::string& layer_name, OGRwkbGeometryType type, const std::vector<std::string>& options = {}) :
-+            m_options(options),
-+            m_dataset(dataset),
-+            m_layer(dataset.get().CreateLayer(layer_name.c_str(), &dataset.srs().get(), type, m_options.get())) {
-+            if (!m_layer) {
-+                throw gdal_error(std::string("failed to create layer '") + layer_name + "'", OGRERR_NONE,
-+                    dataset.driver_name(), dataset.dataset_name(), layer_name);
-+            }
-+        }
-+
-+        OGRLayer& get() {
-+            return *m_layer;
-+        }
-+
-+        const OGRLayer& get() const {
-+            return *m_layer;
-+        }
-+
-+        Dataset& dataset() const {
-+            return m_dataset;
-+        }
-+
-+        const char* name() const {
-+            return m_layer->GetName();
-+        }
-+
-+        Layer& add_field(const std::string& field_name, OGRFieldType type, int width, int precision=0) {
-+            OGRFieldDefn field(field_name.c_str(), type);
-+            field.SetWidth(width);
-+            field.SetPrecision(precision);
-+
-+            if (m_layer->CreateField(&field) != OGRERR_NONE) {
-+                throw gdal_error(std::string("failed to create field '") + field_name + "' in layer '" + name() + "'", OGRERR_NONE,
-+                    m_dataset.driver_name(), m_dataset.dataset_name(), name(), field_name);
-+            }
-+
-+            return *this;
-+        }
-+
-+        Layer& start_transaction() {
-+            OGRErr result = m_layer->StartTransaction();
-+            if (result != OGRERR_NONE) {
-+                throw gdal_error(std::string("starting transaction on layer '") + name() + "' failed", result, m_dataset.driver_name(), m_dataset.dataset_name(), name());
-+            }
-+            return *this;
-+        }
-+
-+        Layer& commit_transaction() {
-+            OGRErr result = m_layer->CommitTransaction();
-+            if (result != OGRERR_NONE) {
-+                throw gdal_error(std::string("committing transaction on layer '") + name() + "' failed", result, m_dataset.driver_name(), m_dataset.dataset_name(), name());
-+            }
-+            return *this;
-+         }
-+
-+    }; // class Layer
-+
-+    class Feature {
-+
-+        Layer& m_layer;
-+        OGRFeature m_feature;
-+
-+    public:
-+
-+        Feature(Layer& layer, std::unique_ptr<OGRGeometry>&& geometry) :
-+            m_layer(layer),
-+            m_feature(m_layer.get().GetLayerDefn()) {
-+            OGRErr result = m_feature.SetGeometryDirectly(geometry.release());
-+            if (result != OGRERR_NONE) {
-+                throw gdal_error(std::string("setting feature geometry in layer '") + m_layer.name() + "' failed", result, m_layer.dataset().driver_name(), m_layer.dataset().dataset_name());
-+            }
-+        }
-+
-+        void add_to_layer() {
-+            OGRErr result = m_layer.get().CreateFeature(&m_feature);
-+            if (result != OGRERR_NONE) {
-+                throw gdal_error(std::string("creating feature in layer '") + m_layer.name() + "' failed", result, m_layer.dataset().driver_name(), m_layer.dataset().dataset_name());
-+            }
-+        }
-+
-+        template <class T>
-+        Feature& set_field(int n, T&& arg) {
-+            m_feature.SetField(n, std::forward<T>(arg));
-+            return *this;
-+        }
-+
-+        template <class T>
-+        Feature& set_field(const char* name, T&& arg) {
-+            m_feature.SetField(name, std::forward<T>(arg));
-+            return *this;
-+        }
-+
-+    }; // class Feature
-+
-+} // namespace gdalcpp
-+
-+#endif // GDALCPP_HPP
---- a/src/CMakeLists.txt
-+++ b/src/CMakeLists.txt
-@@ -6,7 +6,7 @@
- #
- #-----------------------------------------------------------------------------
- 
--add_executable(osmcoastline osmcoastline.cpp coastline_ring.cpp coastline_ring_collection.cpp coastline_polygons.cpp output_database.cpp output_layers.cpp srs.cpp options.cpp)
-+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})
- install(TARGETS osmcoastline DESTINATION bin)
- 
-@@ -18,7 +18,7 @@ add_executable(osmcoastline_segments osm
- target_link_libraries(osmcoastline_segments ${GDAL_LIBRARIES})
- install(TARGETS osmcoastline_segments DESTINATION bin)
- 
--add_executable(osmcoastline_ways osmcoastline_ways.cpp osmcoastline.hpp)
-+add_executable(osmcoastline_ways osmcoastline_ways.cpp return_codes.hpp)
- target_link_libraries(osmcoastline_ways ${OSMIUM_IO_LIBRARIES} ${GDAL_LIBRARIES})
- install(TARGETS osmcoastline_ways DESTINATION bin)
- 
---- a/src/coastline_polygons.cpp
-+++ b/src/coastline_polygons.cpp
-@@ -28,8 +28,9 @@
- 
- #include "coastline_polygons.hpp"
- #include "output_database.hpp"
--#include "osmcoastline.hpp"
-+#include "return_codes.hpp"
- #include "srs.hpp"
-+#include "util.hpp"
- 
- extern SRS srs;
- extern bool debug;
-@@ -73,7 +74,7 @@ unsigned int CoastlinePolygons::fix_dire
-                 // Workaround for bug in OGR: reverseWindingOrder sets dimensions to 3
-                 polygon->getInteriorRing(i)->setCoordinateDimension(2);
-             }
--            m_output.add_error_line(static_cast<OGRLineString*>(er->clone()), "direction");
-+            m_output.add_error_line(make_unique_ptr_clone<OGRLineString>(er), "direction");
-             warnings++;
-         }
-     }
-@@ -83,26 +84,26 @@ unsigned int CoastlinePolygons::fix_dire
- 
- void CoastlinePolygons::transform() {
-     for (const auto& polygon : m_polygons) {
--        srs.transform(polygon);
-+        srs.transform(polygon.get());
-     }
- }
- 
--void CoastlinePolygons::split_geometry(std::unique_ptr<OGRGeometry> geom, int level) {
-+void CoastlinePolygons::split_geometry(std::unique_ptr<OGRGeometry>&& geom, int level) {
-     if (geom->getGeometryType() == wkbPolygon) {
-         geom->assignSpatialReference(srs.out());
--        split_polygon(static_cast<OGRPolygon*>(geom.release()), level);
-+        split_polygon(static_cast_unique_ptr<OGRPolygon>(std::move(geom)), level);
-     } else { // wkbMultiPolygon
--        const auto mp = static_cast<OGRMultiPolygon*>(geom.get());
-+        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)) };
-             mp->removeGeometry(0, false);
-             polygon->assignSpatialReference(srs.out());
--            split_polygon(polygon.release(), level);
-+            split_polygon(std::move(polygon), level);
-         }
-     }
- }
- 
--void CoastlinePolygons::split_polygon(OGRPolygon* polygon, int level) {
-+void CoastlinePolygons::split_polygon(std::unique_ptr<OGRPolygon>&& polygon, int level) {
-     if (level > m_max_split_depth) {
-         m_max_split_depth = level;
-     }
-@@ -193,7 +194,7 @@ void CoastlinePolygons::split() {
-     std::swap(v, m_polygons);
-     m_polygons.reserve(v.size());
-     for (auto& polygon : v) {
--        split_polygon(polygon, 0);
-+        split_polygon(std::move(polygon), 0);
-     }
- }
- 
-@@ -201,12 +202,13 @@ void CoastlinePolygons::output_land_poly
-     if (make_copy) {
-         // because adding to a layer destroys the geometry, we need to copy it if it is needed later
-         for (const auto& polygon : m_polygons) {
--            m_output.add_land_polygon(static_cast<OGRPolygon*>(polygon->clone()));
-+            m_output.add_land_polygon(make_unique_ptr_clone<OGRPolygon>(polygon.get()));
-         }
-     } else {
-         for (auto& polygon : m_polygons) {
--            m_output.add_land_polygon(polygon);
-+            m_output.add_land_polygon(std::move(polygon));
-         }
-+        m_polygons.clear();
-     }
- }
- 
-@@ -273,7 +275,7 @@ void CoastlinePolygons::output_polygon_r
- }
- 
- void CoastlinePolygons::output_lines(int max_points) {
--    for (OGRPolygon* polygon : m_polygons) {
-+    for (const auto& polygon : m_polygons) {
-         output_polygon_ring_as_lines(max_points, polygon->getExteriorRing());
-         for (int i=0; i < polygon->getNumInteriorRings(); ++i) {
-             output_polygon_ring_as_lines(max_points, polygon->getInteriorRing(i));
-@@ -287,25 +289,27 @@ void CoastlinePolygons::split_bbox(OGREn
-         try {
-             std::unique_ptr<OGRGeometry> geom { create_rectangular_polygon(e.MinX, e.MinY, e.MaxX, e.MaxY, m_expand) };
-             assert(geom->getSpatialReference() != nullptr);
--            for (const OGRPolygon* polygon : v) {
--                OGRGeometry* diff = geom->Difference(polygon);
-+            for (const auto& polygon : v) {
-+                std::unique_ptr<OGRGeometry> diff { geom->Difference(polygon.get()) };
-                 // for some reason there is sometimes no srs on the geometries, so we add them on
-                 diff->assignSpatialReference(srs.out());
--                geom.reset(diff);
-+                geom = std::move(diff);
-             }
-             if (geom) {
-                 switch (geom->getGeometryType()) {
-                     case wkbPolygon:
--                        m_output.add_water_polygon(static_cast<OGRPolygon*>(geom.release()));
-+                        m_output.add_water_polygon(static_cast_unique_ptr<OGRPolygon>(std::move(geom)));
-                         break;
--                    case wkbMultiPolygon:
--                        for (int i=static_cast<OGRMultiPolygon*>(geom.get())->getNumGeometries() - 1; i >= 0; --i) {
--                            OGRPolygon* p = static_cast<OGRPolygon*>(static_cast<OGRMultiPolygon*>(geom.get())->getGeometryRef(i));
--                            p->assignSpatialReference(geom->getSpatialReference());
--                            static_cast<OGRMultiPolygon*>(geom.get())->removeGeometry(i, FALSE);
--                            m_output.add_water_polygon(p);
-+                    case wkbMultiPolygon: {
-+                            auto mp = static_cast_unique_ptr<OGRMultiPolygon>(std::move(geom));
-+                            for (int i = mp->getNumGeometries() - 1; i >= 0; --i) {
-+                                auto p = std::unique_ptr<OGRPolygon>(static_cast<OGRPolygon*>(mp->getGeometryRef(i)));
-+                                p->assignSpatialReference(mp->getSpatialReference());
-+                                mp->removeGeometry(i, FALSE);
-+                                m_output.add_water_polygon(std::move(p));
-+                            }
-+                            break;
-                         }
--                        break;
-                     case wkbGeometryCollection:
-                         // XXX
-                         break;
-@@ -355,7 +359,7 @@ void CoastlinePolygons::split_bbox(OGREn
- 
-         polygon_vector_type v1;
-         polygon_vector_type v2;
--        for (OGRPolygon* polygon : v) {
-+        for (auto& polygon : v) {
- 
-             /* You might think re-computing the envelope of all those polygons
-             again and again might take a lot of time, but I benchmarked it and
-@@ -363,11 +367,11 @@ void CoastlinePolygons::split_bbox(OGREn
-             OGREnvelope e;
-             polygon->getEnvelope(&e);
-             if (e1.Intersects(e)) {
--                v1.push_back(polygon);
-+                v1.push_back(std::move(polygon));
-             }
- 
-             if (e2.Intersects(e)) {
--                v2.push_back(polygon);
-+                v2.push_back(std::move(polygon));
-             }
-         }
-         split_bbox(e1, std::move(v1));
-@@ -379,9 +383,9 @@ void CoastlinePolygons::split_bbox(OGREn
- unsigned int CoastlinePolygons::output_water_polygons() {
-     unsigned int warnings = 0;
-     polygon_vector_type v;
--    for (OGRPolygon* polygon : m_polygons) {
-+    for (auto& polygon : m_polygons) {
-         if (polygon->IsValid()) {
--            v.push_back(polygon);
-+            v.push_back(std::move(polygon));
-         } else {
-             std::cerr << "Invalid polygon, trying buffer(0).\n";
-             ++warnings;
---- a/src/coastline_polygons.hpp
-+++ b/src/coastline_polygons.hpp
-@@ -34,7 +34,7 @@ class OGRMultiPolygon;
- class OGREnvelope;
- class OutputDatabase;
- 
--typedef std::vector<OGRPolygon*> polygon_vector_type;
-+typedef std::vector<std::unique_ptr<OGRPolygon>> polygon_vector_type;
- 
- /**
-  * A collection of land polygons created out of coastlines.
-@@ -74,8 +74,8 @@ class CoastlinePolygons {
- 
-     std::unique_ptr<OGRPolygon> create_rectangular_polygon(double x1, double y1, double x2, double y2, double expand=0) const;
- 
--    void split_geometry(std::unique_ptr<OGRGeometry> geom, int level);
--    void split_polygon(OGRPolygon* polygon, int level);
-+    void split_geometry(std::unique_ptr<OGRGeometry>&& geom, int level);
-+    void split_polygon(std::unique_ptr<OGRPolygon>&& polygon, int level);
-     void split_bbox(OGREnvelope e, polygon_vector_type&& v);
- 
-     bool add_segment_to_line(OGRLineString* line, OGRPoint* point1, OGRPoint* point2);
---- a/src/coastline_ring_collection.cpp
-+++ b/src/coastline_ring_collection.cpp
-@@ -126,7 +126,16 @@ unsigned int CoastlineRingCollection::ch
-     return missing_positions;
- }
- 
--void CoastlineRingCollection::add_polygons_to_vector(std::vector<OGRGeometry*>& vector) {
-+bool is_valid_polygon(const OGRGeometry* geometry) {
-+    if (geometry && geometry->getGeometryType() == wkbPolygon) {
-+        const auto polygon = static_cast<const OGRPolygon*>(geometry);
-+        return (polygon->getExteriorRing()->getNumPoints() > 3) && (polygon->getNumInteriorRings() == 0) && geometry->IsValid();
-+    }
-+    return false;
-+}
-+
-+std::vector<OGRGeometry*> CoastlineRingCollection::add_polygons_to_vector() {
-+    std::vector<OGRGeometry*> vector;
-     vector.reserve(m_list.size());
- 
-     for (const auto& ring : m_list) {
-@@ -137,15 +146,17 @@ void CoastlineRingCollection::add_polygo
-                 vector.push_back(p.release());
-             } else {
-                 std::unique_ptr<OGRGeometry> geom { p->Buffer(0) };
--                if (geom && (geom->getGeometryType() == wkbPolygon) && (static_cast<OGRPolygon*>(geom.get())->getExteriorRing()->getNumPoints() > 3) && (static_cast<OGRPolygon*>(geom.get())->getNumInteriorRings() == 0) && geom->IsValid()) {
-+                if (is_valid_polygon(geom.get())) {
-                     geom->assignSpatialReference(srs.wgs84());
--                    vector.push_back(static_cast<OGRPolygon*>(geom.release()));
-+                    vector.push_back(geom.release());
-                 } else {
-                     std::cerr << "Ignoring invalid polygon geometry (ring_id=" << ring->ring_id() << ").\n";
-                 }
-             }
-         }
-     }
-+
-+    return vector;
- }
- 
- unsigned int CoastlineRingCollection::output_rings(OutputDatabase& output) {
-@@ -154,18 +165,18 @@ unsigned int CoastlineRingCollection::ou
-     for (const auto& ring : m_list) {
-         if (ring->is_closed()) {
-             if (ring->npoints() > 3) {
--                output.add_ring(ring->ogr_polygon(m_factory, true).release(), ring->ring_id(), ring->nways(), ring->npoints(), ring->is_fixed());
-+                output.add_ring(ring->ogr_polygon(m_factory, true), ring->ring_id(), ring->nways(), ring->npoints(), ring->is_fixed());
-             } else if (ring->npoints() == 1) {
-                 output.add_error_point(ring->ogr_first_point(), "single_point_in_ring", ring->first_node_id());
-                 warnings++;
-             } else { // ring->npoints() == 2 or 3
--                output.add_error_line(ring->ogr_linestring(m_factory, true).release(), "not_a_ring", ring->ring_id());
-+                output.add_error_line(ring->ogr_linestring(m_factory, true), "not_a_ring", ring->ring_id());
-                 output.add_error_point(ring->ogr_first_point(), "not_a_ring", ring->first_node_id());
-                 output.add_error_point(ring->ogr_last_point(), "not_a_ring", ring->last_node_id());
-                 warnings++;
-             }
-         } else {
--            output.add_error_line(ring->ogr_linestring(m_factory, true).release(), "not_closed", ring->ring_id());
-+            output.add_error_line(ring->ogr_linestring(m_factory, true), "not_closed", ring->ring_id());
-             output.add_error_point(ring->ogr_first_point(), "end_point", ring->first_node_id());
-             output.add_error_point(ring->ogr_last_point(), "end_point", ring->last_node_id());
-             warnings++;
---- a/src/coastline_ring_collection.hpp
-+++ b/src/coastline_ring_collection.hpp
-@@ -105,7 +105,7 @@ public:
- 
-     unsigned int check_positions(bool output_missing);
- 
--    void add_polygons_to_vector(std::vector<OGRGeometry*>& vector);
-+    std::vector<OGRGeometry*> add_polygons_to_vector();
- 
-     unsigned int output_rings(OutputDatabase& output);
- 
---- a/src/ogr_include.hpp
-+++ /dev/null
-@@ -1,42 +0,0 @@
--#ifndef OGR_INCLUDE_HPP
--#define OGR_INCLUDE_HPP
--
--#ifdef _MSC_VER
--# pragma warning(push)
--# pragma warning(disable : 4458)
--# pragma warning(disable : 4251)
--#else
--# pragma GCC diagnostic push
--# ifdef __clang__
--#  pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
--# endif
--# pragma GCC diagnostic ignored "-Wfloat-equal"
--# pragma GCC diagnostic ignored "-Wold-style-cast"
--# pragma GCC diagnostic ignored "-Wpadded"
--# pragma GCC diagnostic ignored "-Wredundant-decls"
--# pragma GCC diagnostic ignored "-Wshadow"
--#endif
--
--/* Strictly speaking the following include would be enough here,
--   but everybody using this file will very likely need the other includes,
--   so we are adding them here, so that not everybody will need all those
--   pragmas to disable warnings. */
--//#include <ogr_geometry.h>
--#include <ogr_api.h>
--#include <ogrsf_frmts.h>
--
--#ifdef _MSC_VER
--# pragma warning(pop)
--#else
--# pragma GCC diagnostic pop
--#endif
--
--struct OGRDataSourceDestroyer {
--    void operator()(OGRDataSource* ptr) {
--        if (ptr) {
--            OGRDataSource::DestroyDataSource(ptr);
--        }
--    }
--};
--
--#endif // OGR_INCLUDE_HPP
---- a/src/options.cpp
-+++ b/src/options.cpp
-@@ -25,7 +25,7 @@
- #include <cstdlib>
- #include <getopt.h>
- 
--#include "osmcoastline.hpp"
-+#include "return_codes.hpp"
- #include "options.hpp"
- 
- Options::Options(int argc, char* argv[]) :
---- a/src/osmcoastline.cpp
-+++ b/src/osmcoastline.cpp
-@@ -27,17 +27,17 @@
- #include <osmium/io/any_input.hpp>
- #include <osmium/visitor.hpp>
- 
--#include "osmcoastline.hpp"
-+#include "return_codes.hpp"
- #include "coastline_ring.hpp"
- #include "coastline_ring_collection.hpp"
- #include "coastline_polygons.hpp"
- #include "output_database.hpp"
--#include "output_layers.hpp"
- 
- #include "options.hpp"
- #include "stats.hpp"
- #include "coastline_handlers.hpp"
- #include "srs.hpp"
-+#include "util.hpp"
- #include "verbose_output.hpp"
- 
- // The global SRS object is used in many places to transform
-@@ -56,8 +56,7 @@ const unsigned int max_warnings = 500;
-  * This function assembles all the coastline rings into one huge multipolygon.
-  */
- polygon_vector_type create_polygons(CoastlineRingCollection& coastline_rings, OutputDatabase& output, unsigned int* warnings, unsigned int* errors) {
--    std::vector<OGRGeometry*> all_polygons;
--    coastline_rings.add_polygons_to_vector(all_polygons);
-+    std::vector<OGRGeometry*> all_polygons = coastline_rings.add_polygons_to_vector();
- 
-     int is_valid;
-     const char* options[] = { "METHOD=ONLY_CCW", nullptr };
-@@ -69,8 +68,10 @@ polygon_vector_type create_polygons(Coas
-         std::cerr << "organizePolygons() done\n";
-     }
- 
--    assert(mega_geometry->getGeometryType() == wkbMultiPolygon);
--    OGRMultiPolygon* mega_multipolygon = static_cast<OGRMultiPolygon*>(mega_geometry.get());
-+    if (mega_geometry->getGeometryType() != wkbMultiPolygon) {
-+        throw std::runtime_error("mega geometry isn't a multipolygon. Something is very wrong!");
-+    }
-+    OGRMultiPolygon* mega_multipolygon = static_cast<OGRMultiPolygon*>(mega_geometry.release());
- 
-     polygon_vector_type polygons;
-     polygons.reserve(mega_multipolygon->getNumGeometries());
-@@ -79,13 +80,13 @@ polygon_vector_type create_polygons(Coas
-         assert(geom->getGeometryType() == wkbPolygon);
-         std::unique_ptr<OGRPolygon> p { static_cast<OGRPolygon*>(geom) };
-         if (p->IsValid()) {
--            polygons.push_back(p.release());
-+            polygons.push_back(std::move(p));
-         } else {
--            output.add_error_line(static_cast<OGRLineString*>(p->getExteriorRing()->clone()), "invalid");
-+            output.add_error_line(make_unique_ptr_clone<OGRLineString>(p->getExteriorRing()), "invalid");
-             std::unique_ptr<OGRGeometry> buf0 { p->Buffer(0) };
-             if (buf0 && buf0->getGeometryType() == wkbPolygon && buf0->IsValid()) {
-                 buf0->assignSpatialReference(srs.wgs84());
--                polygons.emplace_back(static_cast<OGRPolygon*>(buf0.release()));
-+                polygons.push_back(static_cast_unique_ptr<OGRPolygon>(std::move(buf0)));
-                 (*warnings)++;
-             } else {
-                 std::cerr << "Ignoring invalid polygon geometry.\n";
-@@ -95,6 +96,7 @@ polygon_vector_type create_polygons(Coas
-     }
- 
-     mega_multipolygon->removeGeometry(-1, FALSE);
-+    delete mega_multipolygon;
- 
-     return polygons;
- }
-@@ -183,7 +185,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, 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.
---- a/src/osmcoastline.hpp
-+++ /dev/null
-@@ -1,33 +0,0 @@
--#ifndef OSMCOASTLINE_HPP
--#define OSMCOASTLINE_HPP
--
--/*
--
--  Copyright 2012-2015 Jochen Topf <jochen at topf.org>.
--
--  This file is part of OSMCoastline.
--
--  OSMCoastline is free software: you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation, either version 3 of the License, or
--  (at your option) any later version.
--
--  OSMCoastline is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with OSMCoastline.  If not, see <http://www.gnu.org/licenses/>.
--
--*/
--
--enum return_codes {
--    return_code_ok      = 0,
--    return_code_warning = 1,
--    return_code_error   = 2,
--    return_code_fatal   = 3,
--    return_code_cmdline = 4
--};
--
--#endif // OSMCOASTLINE_HPP
---- a/src/osmcoastline_filter.cpp
-+++ b/src/osmcoastline_filter.cpp
-@@ -28,7 +28,7 @@
- #include <osmium/handler.hpp>
- #include <osmium/osm/entity_bits.hpp>
- 
--#include "osmcoastline.hpp"
-+#include "return_codes.hpp"
- 
- void print_help() {
-     std::cout << "osmcoastline_filter [OPTIONS] OSMFILE\n"
---- a/src/osmcoastline_segments.cpp
-+++ b/src/osmcoastline_segments.cpp
-@@ -35,9 +35,9 @@
- #include <osmium/osm/undirected_segment.hpp>
- #include <osmium/util/memory_mapping.hpp>
- 
--#include "ogr_include.hpp"
--#include "osmcoastline.hpp"
--#include "srs.hpp"
-+#include <gdalcpp.hpp>
-+
-+#include "return_codes.hpp"
- 
- typedef std::vector<osmium::UndirectedSegment> segvec;
- 
-@@ -73,56 +73,22 @@ public:
- void print_help() {
- }
- 
--void add_segment(OGRLayer* layer, int change, const osmium::UndirectedSegment& segment) {
--    OGRFeature* feature = OGRFeature::CreateFeature(layer->GetLayerDefn());
--
--    auto linestring = new OGRLineString();
-+void add_segment(gdalcpp::Layer& layer, int change, const osmium::UndirectedSegment& segment) {
-+    auto linestring = std::unique_ptr<OGRLineString>(new OGRLineString());
-     linestring->addPoint(segment.first().lon(), segment.first().lat());
-     linestring->addPoint(segment.second().lon(), segment.second().lat());
- 
--    feature->SetGeometryDirectly(linestring);
--    feature->SetField("change", change);
--
--    if (layer->CreateFeature(feature) != OGRERR_NONE) {
--        std::cerr << "Failed to create feature on layer 'changes'.\n";
--        exit(return_code_fatal);
--    }
--
--    OGRFeature::DestroyFeature(feature);
-+    gdalcpp::Feature feature(layer, std::move(linestring));
-+    feature.set_field("change", change);
-+    feature.add_to_layer();
- }
- 
- void output_ogr(const std::string& filename, const std::string& driver_name, const segvec& removed_segments, const segvec& added_segments) {
--    OGRRegisterAll();
--
--    OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str());
--    if (!driver) {
--        std::cerr << driver_name << " driver not available.\n";
--        exit(return_code_fatal);
--    }
--
--    //const char* options[] = { "SPATIALITE=yes", "OGR_SQLITE_SYNCHRONOUS=OFF", "INIT_WITH_EPSG=no", nullptr };
--    const char* options[] = { nullptr };
--    auto data_source = std::unique_ptr<OGRDataSource, OGRDataSourceDestroyer>(driver->CreateDataSource(filename.c_str(), const_cast<char**>(options)));
--    if (!data_source) {
--        std::cerr << "Creation of output file failed.\n";
--        exit(return_code_fatal);
--    }
--
--    SRS srs;
--    auto layer = data_source->CreateLayer("changes", srs.out(), wkbLineString, const_cast<char**>(options));
--    if (!layer) {
--        std::cerr << "Creating layer 'changes' failed.\n";
--        exit(return_code_fatal);
--    }
--
--    OGRFieldDefn field_change("change", OFTInteger);
--    field_change.SetWidth(1);
--    if (layer->CreateField(&field_change) != OGRERR_NONE ) {
--        std::cerr << "Creating field 'change' on 'changes' layer failed.\n";
--        exit(return_code_fatal);
--    }
-+    gdalcpp::Dataset dataset{driver_name, filename};
- 
--    layer->StartTransaction();
-+    gdalcpp::Layer layer{dataset, "changes", wkbLineString};
-+    layer.add_field("change", OFTInteger, 1);
-+    layer.start_transaction();
- 
-     for (const auto& segment : removed_segments) {
-         add_segment(layer, 0, segment);
-@@ -132,7 +98,7 @@ void output_ogr(const std::string& filen
-         add_segment(layer, 1, segment);
-     }
- 
--    layer->CommitTransaction();
-+    layer.commit_transaction();
- }
- 
- int main(int argc, char *argv[]) {
---- a/src/osmcoastline_ways.cpp
-+++ b/src/osmcoastline_ways.cpp
-@@ -20,7 +20,7 @@
- */
- 
- #include <iostream>
--#include <set>
-+#include <memory>
- #include <string>
- 
- #include <osmium/geom/haversine.hpp>
-@@ -30,8 +30,9 @@
- #include <osmium/io/any_input.hpp>
- #include <osmium/visitor.hpp>
- 
--#include "ogr_include.hpp"
--#include "osmcoastline.hpp"
-+#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;
-@@ -40,94 +41,41 @@ class CoastlineWaysHandler : public osmi
- 
-     double m_length;
- 
--    std::unique_ptr<OGRDataSource, OGRDataSourceDestroyer> m_data_source;
--    OGRLayer* m_layer_ways;
-+    gdalcpp::Dataset m_dataset;
-+    gdalcpp::Layer m_layer_ways;
- 
-     osmium::geom::OGRFactory<> m_factory;
- 
- public:
- 
-     CoastlineWaysHandler(const std::string& db_filename) :
--        m_length(0.0) {
--        OGRRegisterAll();
--
--        const char* driver_name = "SQLite";
--        OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name);
--        if (!driver) {
--            std::cerr << driver_name << " driver not available.\n";
--            exit(return_code_fatal);
--        }
--
--        CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
--        const char* options[] = { "SPATIALITE=TRUE", nullptr };
--        m_data_source.reset(driver->CreateDataSource(db_filename.c_str(), const_cast<char**>(options)));
--        if (!m_data_source) {
--            std::cerr << "Creation of output file failed.\n";
--            exit(return_code_fatal);
--        }
--
--        OGRSpatialReference sparef;
--        sparef.SetWellKnownGeogCS("WGS84");
--        m_layer_ways = m_data_source->CreateLayer("ways", &sparef, wkbLineString, nullptr);
--        if (!m_layer_ways) {
--            std::cerr << "Layer creation failed.\n";
--            exit(return_code_fatal);
--        }
--
--        OGRFieldDefn field_way_id("way_id", OFTString);
--        field_way_id.SetWidth(10);
--        if (m_layer_ways->CreateField(&field_way_id) != OGRERR_NONE ) {
--            std::cerr << "Creating field 'way_id' on 'ways' layer failed.\n";
--            exit(return_code_fatal);
--        }
--
--        OGRFieldDefn field_name("name", OFTString);
--        field_name.SetWidth(100);
--        if (m_layer_ways->CreateField(&field_name) != OGRERR_NONE ) {
--            std::cerr << "Creating field 'name' on 'ways' layer failed.\n";
--            exit(return_code_fatal);
--        }
--
--        OGRFieldDefn field_source("source", OFTString);
--        field_source.SetWidth(255);
--        if (m_layer_ways->CreateField(&field_source) != OGRERR_NONE ) {
--            std::cerr << "Creating field 'source' on 'ways' layer failed.\n";
--            exit(return_code_fatal);
--        }
--
--        OGRFieldDefn field_bogus("bogus", OFTString);
--        field_bogus.SetWidth(1);
--        if (m_layer_ways->CreateField(&field_bogus) != OGRERR_NONE ) {
--            std::cerr << "Creating field 'bogus' on 'ways' layer failed.\n";
--            exit(return_code_fatal);
--        }
--
--        m_layer_ways->StartTransaction();
-+        m_length(0.0),
-+        m_dataset("SQLite", db_filename, gdalcpp::SRS{}, {"SPATIALITE=TRUE", "OGR_SQLITE_SYNCHRONOUS=OFF", "INIT_WITH_EPSG=no" }),
-+        m_layer_ways(m_dataset, "ways", wkbLineString) {
-+
-+        m_layer_ways.add_field("way_id", OFTString, 10);
-+        m_layer_ways.add_field("name",   OFTString, 100);
-+        m_layer_ways.add_field("source", OFTString, 255);
-+        m_layer_ways.add_field("bogus",  OFTString, 1);
-+        m_layer_ways.start_transaction();
-     }
- 
-     ~CoastlineWaysHandler() {
--        m_layer_ways->CommitTransaction();
-+        m_layer_ways.commit_transaction();
-     }
- 
-     void way(osmium::Way& way) {
-         m_length += osmium::geom::haversine::distance(way.nodes());
-         try {
--            OGRFeature* feature = OGRFeature::CreateFeature(m_layer_ways->GetLayerDefn());
-             std::unique_ptr<OGRLineString> ogrlinestring = m_factory.create_linestring(way);
--            feature->SetGeometry(ogrlinestring.get());
--            feature->SetField("way_id", std::to_string(way.id()).c_str());
--            feature->SetField("name", way.tags().get_value_by_key("name"));
--            feature->SetField("source", way.tags().get_value_by_key("source"));
-+            gdalcpp::Feature feature(m_layer_ways, std::move(ogrlinestring));
-+            feature.set_field("way_id", std::to_string(way.id()).c_str());
-+            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->SetField("bogus", (coastline && !strcmp(coastline, "bogus")) ? "t" : "f");
--
--            if (m_layer_ways->CreateFeature(feature) != OGRERR_NONE) {
--                std::cerr << "Failed to create feature.\n";
--                exit(1);
--            }
--
--            OGRFeature::DestroyFeature(feature);
-+            feature.set_field("bogus", (coastline && !std::strcmp(coastline, "bogus")) ? "t" : "f");
-+            feature.add_to_layer();
-         } catch (osmium::geometry_error&) {
-             std::cerr << "Ignoring illegal geometry for way " << way.id() << ".\n";
-         }
---- a/src/output_database.cpp
-+++ b/src/output_database.cpp
-@@ -22,54 +22,49 @@
- #include <iostream>
- #include <sstream>
- 
--#include "ogr_include.hpp"
--#include "osmcoastline.hpp"
--#include "output_database.hpp"
--#include "output_layers.hpp"
-+#include <gdal_version.h>
-+#include <geos_c.h>
-+
- #include "options.hpp"
-+#include "output_database.hpp"
-+#include "srs.hpp"
- #include "stats.hpp"
- 
--const char* OutputDatabase::options_with_index[] = { nullptr };
--const char* OutputDatabase::options_without_index[] = { "SPATIAL_INDEX=no", nullptr };
--
--OutputDatabase::~OutputDatabase() {
--    OGRCleanupAll();
--}
--
--OutputDatabase::OutputDatabase(const std::string& outdb, bool with_index) :
-+OutputDatabase::OutputDatabase(const std::string& outdb, SRS& srs, bool with_index) :
-     m_with_index(with_index),
--    m_data_source(),
--    m_layer_error_points(),
--    m_layer_error_lines(),
--    m_layer_rings(),
--    m_layer_land_polygons(),
--    m_layer_water_polygons(),
--    m_layer_lines() {
--    OGRRegisterAll();
--
--    const char* driver_name = "SQLite";
--    OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name);
--    if (!driver) {
--        std::cerr << driver_name << " driver not available.\n";
--        exit(return_code_fatal);
--    }
-+    m_srs(srs),
-+    m_dataset("SQLite", outdb, gdalcpp::SRS(*srs.out()), { "SPATIALITE=TRUE", "OGR_SQLITE_SYNCHRONOUS=OFF", "INIT_WITH_EPSG=no" }),
-+    m_layer_error_points(m_dataset, "error_points", wkbPoint, layer_options()),
-+    m_layer_error_lines(m_dataset, "error_lines", wkbLineString, layer_options()),
-+    m_layer_rings(m_dataset, "rings", wkbPolygon, layer_options()),
-+    m_layer_land_polygons(m_dataset, "land_polygons", wkbPolygon, layer_options()),
-+    m_layer_water_polygons(m_dataset, "water_polygons", wkbPolygon, layer_options()),
-+    m_layer_lines(m_dataset, "lines", wkbLineString, layer_options()) {
-+
-+    m_layer_error_points.add_field("osm_id", OFTString, 10);
-+    m_layer_error_points.add_field("error", OFTString, 16);
-+    m_layer_error_points.start_transaction();
-+
-+    m_layer_error_lines.add_field("osm_id", OFTString, 10);
-+    m_layer_error_lines.add_field("error", OFTString, 16);
-+    m_layer_error_lines.start_transaction();
-+
-+    m_layer_rings.add_field("osm_id",  OFTString, 10);
-+    m_layer_rings.add_field("nways",   OFTInteger, 6);
-+    m_layer_rings.add_field("npoints", OFTInteger, 8);
-+    m_layer_rings.add_field("fixed",   OFTInteger, 1);
-+    m_layer_rings.add_field("land",    OFTInteger, 1);
-+    m_layer_rings.add_field("valid",   OFTInteger, 1);
-+    m_layer_rings.start_transaction();
- 
--    const char* options[] = { "SPATIALITE=yes", "OGR_SQLITE_SYNCHRONOUS=OFF", "INIT_WITH_EPSG=no", nullptr };
--    m_data_source.reset(driver->CreateDataSource(outdb.c_str(), const_cast<char**>(options)));
--    if (!m_data_source) {
--        std::cerr << "Creation of output file failed.\n";
--        exit(return_code_fatal);
--    }
-+    m_layer_land_polygons.start_transaction();
- 
--    m_layer_error_points.reset(new LayerErrorPoints(m_data_source.get(), layer_options()));
--    m_layer_error_lines.reset(new LayerErrorLines(m_data_source.get(), layer_options()));
--    m_layer_rings.reset(new LayerRings(m_data_source.get(), layer_options()));
--    m_layer_land_polygons.reset(new LayerPolygons(m_data_source.get(), layer_options(), "land_polygons"));
--    m_layer_water_polygons.reset(new LayerPolygons(m_data_source.get(), layer_options(), "water_polygons"));
--    m_layer_lines.reset(new LayerLines(m_data_source.get(), layer_options()));
-+    m_layer_water_polygons.start_transaction();
- 
--    exec("CREATE TABLE options (overlap REAL, close_distance REAL, max_points_in_polygons INTEGER, split_large_polygons INTEGER)");
--    exec("CREATE TABLE meta ("
-+    m_layer_lines.start_transaction();
-+
-+    m_dataset.exec("CREATE TABLE options (overlap REAL, close_distance REAL, max_points_in_polygons INTEGER, split_large_polygons INTEGER)");
-+    m_dataset.exec("CREATE TABLE meta ("
-          "timestamp                      TEXT, "
-          "runtime                        INTEGER, "
-          "memory_usage                   INTEGER, "
-@@ -99,7 +94,7 @@ void OutputDatabase::set_options(const O
-         << (options.split_large_polygons ? 1 : 0)
-         << ")";
- 
--    exec(sql.str().c_str());
-+    m_dataset.exec(sql.str());
- }
- 
- void OutputDatabase::set_meta(int runtime, int memory_usage, const Stats& stats) {
-@@ -120,59 +115,124 @@ void OutputDatabase::set_meta(int runtim
-         << stats.land_polygons_after_split
-         << ")";
- 
--    exec(sql.str().c_str());
-+    m_dataset.exec(sql.str());
- }
- 
- void OutputDatabase::commit() {
--    m_layer_lines->commit();
--    m_layer_water_polygons->commit();
--    m_layer_land_polygons->commit();
--    m_layer_rings->commit();
--    m_layer_error_lines->commit();
--    m_layer_error_points->commit();
--}
--
--void OutputDatabase::add_error_point(std::unique_ptr<OGRPoint> point, const char* error, osmium::object_id_type id) {
--    m_layer_error_points->add(point.release(), error, id);
--}
--
--void OutputDatabase::add_error_point(OGRPoint* point, const char* error, osmium::object_id_type id) {
--    m_layer_error_points->add(point, error, id);
--}
--
--void OutputDatabase::add_error_line(std::unique_ptr<OGRLineString> linestring, const char* error, osmium::object_id_type id) {
--    m_layer_error_lines->add(linestring.release(), error, id);
--}
--
--void OutputDatabase::add_error_line(OGRLineString* linestring, const char* error, osmium::object_id_type id) {
--    m_layer_error_lines->add(linestring, error, id);
--}
--
--void OutputDatabase::add_ring(std::unique_ptr<OGRPolygon> polygon, int id, int nways, int npoints, bool fixed) {
--    layer_rings()->add(polygon.release(), id, nways, npoints, fixed, layer_error_points());
--}
--
--void OutputDatabase::add_ring(OGRPolygon* polygon, int id, int nways, int npoints, bool fixed) {
--    layer_rings()->add(polygon, id, nways, npoints, fixed, layer_error_points());
--}
--
--void OutputDatabase::add_land_polygon(OGRPolygon* polygon) {
--    layer_land_polygons()->add(polygon);
--}
--
--void OutputDatabase::add_water_polygon(OGRPolygon* polygon) {
--    layer_water_polygons()->add(polygon);
--}
--
--void OutputDatabase::add_line(std::unique_ptr<OGRLineString> linestring) {
--    layer_lines()->add(linestring.release());
--}
--
--const char** OutputDatabase::layer_options() const {
--    return m_with_index ? options_with_index : options_without_index;
--}
-+    m_layer_lines.commit_transaction();
-+    m_layer_water_polygons.commit_transaction();
-+    m_layer_land_polygons.commit_transaction();
-+    m_layer_rings.commit_transaction();
-+    m_layer_error_lines.commit_transaction();
-+    m_layer_error_points.commit_transaction();
-+}
-+
-+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));
-+    feature.set_field("osm_id", std::to_string(id).c_str());
-+    feature.set_field("error", error);
-+    feature.add_to_layer();
-+}
-+
-+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));
-+    feature.set_field("osm_id", std::to_string(id).c_str());
-+    feature.set_field("error", error);
-+    feature.add_to_layer();
-+}
-+
-+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();
-+
-+    if (!valid) {
-+        /*
-+           When the polygon is invalid we find out what and where the problem is.
-+           This code is a bit strange because older versions of the GEOS library
-+           only export this information as a string. We parse the reason and
-+           point coordinates (of a self-intersection-point for instance) from
-+           this string and create a point in the error layer for it.
-+
-+           The exportToGEOS() method on OGR geometries is not documented. Let's
-+           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();
-+        auto r = GEOSisValidReason(polygon->exportToGEOS(contextHandle));
-+        std::string reason = r ? r : "";
-+        OGRGeometry::freeGEOSContext(contextHandle);
-+#endif
-+
-+        if (!reason.empty()) {
-+            size_t left_bracket = reason.find('[');
-+            size_t right_bracket = reason.find(']');
-+
-+            std::istringstream iss(reason.substr(left_bracket+1, right_bracket-left_bracket-1), std::istringstream::in);
-+            double x;
-+            double y;
-+            iss >> x;
-+            iss >> y;
-+            reason = reason.substr(0, left_bracket);
-+
-+            std::unique_ptr<OGRPoint> point { new OGRPoint() };
-+            point->assignSpatialReference(polygon->getSpatialReference());
-+            point->setX(x);
-+            point->setY(y);
-+
-+            if (reason == "Self-intersection") {
-+                reason = "self_intersection";
-+            }
-+            add_error_point(std::move(point), reason.c_str(), osm_id);
-+        } else {
-+            std::cerr << "Did not get reason from GEOS why polygon " << osm_id << " is invalid. Could not write info to error points layer\n";
-+        }
-+    }
- 
--void OutputDatabase::exec(const char* sql) {
--    m_data_source->ReleaseResultSet(m_data_source->ExecuteSQL(sql, nullptr, nullptr));
-+    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);
-+    feature.set_field("fixed", fixed);
-+    feature.set_field("land", land);
-+    feature.set_field("valid", valid);
-+    feature.add_to_layer();
-+}
-+
-+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));
-+    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));
-+    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));
-+    feature.add_to_layer();
-+}
-+
-+std::vector<std::string> OutputDatabase::layer_options() const {
-+    std::vector<std::string> options;
-+    if (!m_with_index) {
-+        options.emplace_back("SPATIAL_INDEX=no");
-+    }
-+    return options;
- }
- 
---- a/src/output_database.hpp
-+++ b/src/output_database.hpp
-@@ -24,18 +24,13 @@
- 
- #include <memory>
- #include <string>
-+#include <vector>
- 
- #include <osmium/osm/types.hpp>
--#include <ogr_spatialref.h>
- 
--#include "ogr_include.hpp"
--
--class LayerErrorPoints;
--class LayerErrorLines;
--class LayerRings;
--class LayerPolygons;
--class LayerLines;
-+#include <gdalcpp.hpp>
- 
-+class SRS;
- class Options;
- struct Stats;
- 
-@@ -46,54 +41,50 @@ struct Stats;
-  */
- class OutputDatabase {
- 
--    static const char* options_without_index[];
--    static const char* options_with_index[];
--
-     bool m_with_index;
- 
--    std::unique_ptr<OGRDataSource, OGRDataSourceDestroyer> m_data_source;
-+    SRS& m_srs;
-+
-+    gdalcpp::Dataset m_dataset;
-+
-+    // Any errors in a linestring
-+    gdalcpp::Layer m_layer_error_points;
-+
-+    // Any errors in a point
-+    gdalcpp::Layer m_layer_error_lines;
-+
-+    // Layer for polygon rings.
-+    // Will contain polygons without holes, ie. with just an outer ring.
-+    // Polygon outer rings will be oriented according to usual GIS custom with
-+    // points going clockwise around the ring, ie "land" is on the right hand
-+    // side of the border. This is the other way around from how it looks in
-+    // OSM.
-+    gdalcpp::Layer m_layer_rings;
-+
-+    // Completed land polygons.
-+    gdalcpp::Layer m_layer_land_polygons;
- 
--    std::unique_ptr<LayerErrorPoints> m_layer_error_points;
--    std::unique_ptr<LayerErrorLines>  m_layer_error_lines;
--    std::unique_ptr<LayerRings>       m_layer_rings;
--    std::unique_ptr<LayerPolygons>    m_layer_land_polygons;
--    std::unique_ptr<LayerPolygons>    m_layer_water_polygons;
--    std::unique_ptr<LayerLines>       m_layer_lines;
-+    // Completed water polygons.
-+    gdalcpp::Layer m_layer_water_polygons;
- 
--    const char** layer_options() const;
-+    // Coastlines generated from completed polygons.
-+    // Lines contain at most max-points points.
-+    gdalcpp::Layer m_layer_lines;
- 
--    /// Execute arbitrary SQL command on database
--    void exec(const char* sql);
-+    std::vector<std::string> layer_options() const;
- 
- public:
- 
--    OutputDatabase(const std::string& outdb, bool with_index=false);
-+    OutputDatabase(const std::string& outdb, SRS& srs, bool with_index=false);
- 
--    ~OutputDatabase();
-+    ~OutputDatabase() noexcept = default;
- 
--    void create_layer_error_points();
--    void create_layer_error_lines();
--    void create_layer_rings();
--    void create_layer_land_polygons();
--    void create_layer_water_polygons();
--    void create_layer_lines();
--
--    LayerErrorPoints* layer_error_points()   const { return m_layer_error_points.get(); }
--    LayerErrorLines*  layer_error_lines()    const { return m_layer_error_lines.get(); }
--    LayerRings*       layer_rings()          const { return m_layer_rings.get(); }
--    LayerPolygons*    layer_land_polygons()  const { return m_layer_land_polygons.get(); }
--    LayerPolygons*    layer_water_polygons() const { return m_layer_water_polygons.get(); }
--    LayerLines*       layer_lines()          const { return m_layer_lines.get(); }
--
--    void add_error_point(std::unique_ptr<OGRPoint> point, const char* error, osmium::object_id_type id=0);
--    void add_error_point(OGRPoint* point, const char* error, osmium::object_id_type id=0);
--    void add_error_line(std::unique_ptr<OGRLineString> linestring, const char* error, osmium::object_id_type id=0);
--    void add_error_line(OGRLineString* linestring, const char* error, osmium::object_id_type id=0);
--    void add_ring(std::unique_ptr<OGRPolygon> polygon, int id, int nways, int npoints, bool fixed);
--    void add_ring(OGRPolygon* polygon, int id, int nways, int npoints, bool fixed);
--    void add_land_polygon(OGRPolygon* polygon);
--    void add_water_polygon(OGRPolygon* polygon);
--    void add_line(std::unique_ptr<OGRLineString> linestring);
-+    void add_error_point(std::unique_ptr<OGRPoint>&& point, const char* error, osmium::object_id_type id=0);
-+    void add_error_line(std::unique_ptr<OGRLineString>&& linestring, const char* error, osmium::object_id_type id=0);
-+    void add_ring(std::unique_ptr<OGRPolygon>&& polygon, int osm_id, int nways, int npoints, bool fixed);
-+    void add_land_polygon(std::unique_ptr<OGRPolygon>&& polygon);
-+    void add_water_polygon(std::unique_ptr<OGRPolygon>&& polygon);
-+    void add_line(std::unique_ptr<OGRLineString>&& linestring);
- 
-     void set_options(const Options& options);
-     void set_meta(int runtime, int memory_usage, const Stats& stats);
---- a/src/output_layers.hpp
-+++ /dev/null
-@@ -1,124 +0,0 @@
--#ifndef OUTPUT_LAYER_HPP
--#define OUTPUT_LAYER_HPP
--
--/*
--
--  Copyright 2012-2015 Jochen Topf <jochen at topf.org>.
--
--  This file is part of OSMCoastline.
--
--  OSMCoastline is free software: you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation, either version 3 of the License, or
--  (at your option) any later version.
--
--  OSMCoastline is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with OSMCoastline.  If not, see <http://www.gnu.org/licenses/>.
--
--*/
--
--#include <osmium/osm/types.hpp>
--
--#include "srs.hpp"
--
--extern SRS srs;
--
--class OGRLayer;
--class OGRDataSource;
--class OGRPoint;
--class OGRLineString;
--class OGRPolygon;
--
--/**
-- * Parent class for all output layers.
-- */
--class Layer {
--
--protected:
--
--    /// OGRLayer implementing this output layer.
--    OGRLayer* m_layer;
--
--    Layer() : m_layer(nullptr) {}
--
--public:
--
--    /// Commit transaction on this layer.
--    void commit();
--
--};
--
--/**
-- * Layer for any errors in one point.
-- */
--class LayerErrorPoints : public Layer {
--
--public:
--
--    LayerErrorPoints(OGRDataSource* data_source, const char** options);
--    void add(OGRPoint* point, const char* error, osmium::object_id_type id);
--
--};
--
--/**
-- * Layer for any errors in a linestring.
-- */
--class LayerErrorLines : public Layer {
--
--public:
--
--    LayerErrorLines(OGRDataSource* data_source, const char** options);
--    void add(OGRLineString* linestring, const char* error, osmium::object_id_type id);
--
--};
--
--/**
-- * Layer for polygon rings.
-- * Will contain polygons without holes, ie. with just an outer ring.
-- * Polygon outer rings will be oriented according to usual GIS custom with
-- * points going clockwise around the ring, ie "land" is on the right hand side of
-- * the border. This is the other way around from how it looks in OSM.
-- */
--class LayerRings : public Layer {
--
--public:
--
--    LayerRings(OGRDataSource* data_source, const char** options);
--    void add(OGRPolygon* polygon, int id, int nways, int npoints, bool fixed, LayerErrorPoints* layer_error_points);
--
--};
--
--/**
-- * Layer for completed polygons.
-- * Polygons can contain inner rings for large water areas such as the Caspian Sea.
-- */
--class LayerPolygons : public Layer {
--
--    const char* m_name;
--
--public:
--
--    LayerPolygons(OGRDataSource* data_source, const char** options, const char* name);
--    void add(OGRPolygon* polygon);
--
--};
--
--/**
-- * Layer for coastlines generated from completed polygons.
-- * Lines containt at most max-points points.
-- */
--class LayerLines : public Layer {
--
--public:
--
--    LayerLines(OGRDataSource* data_source, const char** options);
--    void add(OGRLineString* lines);
--
--};
--
--#endif // OUTPUT_LAYER_HPP
---- /dev/null
-+++ b/src/return_codes.hpp
-@@ -0,0 +1,33 @@
-+#ifndef OSMCOASTLINE_HPP
-+#define OSMCOASTLINE_HPP
-+
-+/*
-+
-+  Copyright 2012-2015 Jochen Topf <jochen at topf.org>.
-+
-+  This file is part of OSMCoastline.
-+
-+  OSMCoastline is free software: you can redistribute it and/or modify
-+  it under the terms of the GNU General Public License as published by
-+  the Free Software Foundation, either version 3 of the License, or
-+  (at your option) any later version.
-+
-+  OSMCoastline is distributed in the hope that it will be useful,
-+  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+  GNU General Public License for more details.
-+
-+  You should have received a copy of the GNU General Public License
-+  along with OSMCoastline.  If not, see <http://www.gnu.org/licenses/>.
-+
-+*/
-+
-+enum return_codes {
-+    return_code_ok      = 0,
-+    return_code_warning = 1,
-+    return_code_error   = 2,
-+    return_code_fatal   = 3,
-+    return_code_cmdline = 4
-+};
-+
-+#endif // OSMCOASTLINE_HPP
---- /dev/null
-+++ b/src/util.hpp
-@@ -0,0 +1,41 @@
-+#ifndef UTIL_HPP
-+#define UTIL_HPP
-+
-+/*
-+
-+  Copyright 2012-2015 Jochen Topf <jochen at topf.org>.
-+
-+  This file is part of OSMCoastline.
-+
-+  OSMCoastline is free software: you can redistribute it and/or modify
-+  it under the terms of the GNU General Public License as published by
-+  the Free Software Foundation, either version 3 of the License, or
-+  (at your option) any later version.
-+
-+  OSMCoastline is distributed in the hope that it will be useful,
-+  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+  GNU General Public License for more details.
-+
-+  You should have received a copy of the GNU General Public License
-+  along with OSMCoastline.  If not, see <http://www.gnu.org/licenses/>.
-+
-+*/
-+
-+#include <memory>
-+#include <type_traits>
-+
-+template <typename R, typename T>
-+std::unique_ptr<R> make_unique_ptr_clone(const T* source) {
-+    static_assert(std::is_convertible<T*, R*>::value, "T* must be convertible to R*");
-+    return std::unique_ptr<R>(static_cast<R*>(source->clone()));
-+}
-+
-+template <typename TDerived, typename TBase>
-+std::unique_ptr<TDerived> static_cast_unique_ptr(std::unique_ptr<TBase>&& ptr) {
-+    static_assert(std::is_base_of<TBase, TDerived>::value, "TDerived must be derived from TBase");
-+    return std::unique_ptr<TDerived>(static_cast<TDerived*>(ptr.release()));
-+}
-+
-+
-+#endif // UTIL_HPP
diff --git a/debian/patches/series b/debian/patches/series
deleted file mode 100644
index f64181c..0000000
--- a/debian/patches/series
+++ /dev/null
@@ -1 +0,0 @@
-0001-Switch-to-gdalcpp.hpp.-Adds-support-for-GDAL-2.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/osmcoastline.git



More information about the Pkg-grass-devel mailing list