[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