[osmcoastline] 01/06: Imported Upstream version 2.1.0

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Tue Aug 18 14:19:59 UTC 2015


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

sebastic pushed a commit to branch master
in repository osmcoastline.

commit a3160fa08cd54b6ad89abf1b9e171ca423a55f1c
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Tue Aug 18 16:13:20 2015 +0200

    Imported Upstream version 2.1.0
---
 CHANGELOG.md                       |  22 +++-
 CMakeLists.txt                     |  12 ++-
 README.md                          |   2 +-
 cmake/FindOSMPBF.cmake             |  50 ---------
 cmake/FindOsmium.cmake             |  10 +-
 man/manpage.template               |   3 +-
 man/osmcoastline.md                |  29 ++++-
 man/osmcoastline_segments.md       |  69 ++++++++++++
 simplify_and_split/split_tiles.sql |   3 +-
 src/CMakeLists.txt                 |   4 +
 src/coastline_ring_collection.cpp  |  10 +-
 src/coastline_ring_collection.hpp  |   2 +-
 src/options.cpp                    |   8 +-
 src/options.hpp                    |   3 +
 src/osmcoastline.cpp               |  19 +++-
 src/osmcoastline_filter.cpp        |   2 -
 src/osmcoastline_segments.cpp      | 214 +++++++++++++++++++++++++++++++++++++
 src/osmcoastline_ways.cpp          |   2 -
 18 files changed, 384 insertions(+), 80 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 900c06b..5a47519 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,25 @@ This project adheres to [Semantic Versioning](http://semver.org/).
 
 ## [unreleased] -
 
+### Added
+
+### Changed
+
+### Fixed
+
+
+## [2.1.0] - 2015-08-18
+
+### Added
+
+- Optionally writes out list of all coastline segments and the new program
+  `osmcoastline_segments` can compare those lists in various ways.
+
+### Changed
+
+- Updates for new libosmium version
+
+
 ## [2.0.1] - 2015-03-31
 
 ### Changed
@@ -13,6 +32,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
 - Added man pages
 
 
-[unreleased]: https://github.com/osmcode/osmium-tool/compare/v2.0.1...HEAD
+[unreleased]: https://github.com/osmcode/osmium-tool/compare/v2.1.0...HEAD
+[2.1.0]: https://github.com/osmcode/osmium-tool/compare/v2.0.1...v2.1.0
 [2.0.1]: https://github.com/osmcode/osmium-tool/compare/v2.0.0...v2.0.1
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7d8b573..c8ed758 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,6 +9,8 @@
 cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
 
 #-----------------------------------------------------------------------------
 #
@@ -19,8 +21,8 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 project(osmcoastline)
 
 set(OSMCOASTLINE_VERSION_MAJOR 2)
-set(OSMCOASTLINE_VERSION_MINOR 0)
-set(OSMCOASTLINE_VERSION_PATCH 1)
+set(OSMCOASTLINE_VERSION_MINOR 1)
+set(OSMCOASTLINE_VERSION_PATCH 0)
 
 set(OSMCOASTLINE_VERSION
     ${OSMCOASTLINE_VERSION_MAJOR}.${OSMCOASTLINE_VERSION_MINOR}.${OSMCOASTLINE_VERSION_PATCH})
@@ -178,7 +180,7 @@ function(add_man_page _section _name)
             --variable "section=${_section}"
             -o ${_output_file}
             ${_source_file}
-        DEPENDS ${_source_file}
+        DEPENDS ${_source_file} man/manpage.template
         WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
         COMMENT "Building manpage ${_name}.${_section}"
         VERBATIM)
@@ -189,13 +191,12 @@ endfunction()
 if(PANDOC)
     message(STATUS "Looking for pandoc - found")
     message(STATUS "  Manual pages will be built")
-    execute_process(COMMAND date "+%Y-%m-%d" OUTPUT_VARIABLE PUBDATE OUTPUT_STRIP_TRAILING_WHITESPACE)
     set(PANDOC_MAN_OPTIONS
         -s
         -t man
         --template ${CMAKE_CURRENT_SOURCE_DIR}/man/manpage.template
         --variable "description=osmcoastline/${OSMCOASTLINE_VERSION}"
-        --variable "date=${PUBDATE}"
+        --variable "version=${OSMCOASTLINE_VERSION}"
         --variable "author=${AUTHOR}"
     )
     set(PANDOC_HTML_OPTIONS -s -t html)
@@ -203,6 +204,7 @@ if(PANDOC)
     add_man_page(1 osmcoastline)
     add_man_page(1 osmcoastline_filter)
     add_man_page(1 osmcoastline_readmeta)
+    add_man_page(1 osmcoastline_segments)
     add_man_page(1 osmcoastline_ways)
 
     install(DIRECTORY ${CMAKE_BINARY_DIR}/man DESTINATION share)
diff --git a/README.md b/README.md
index 78bf4b7..7a8c656 100644
--- a/README.md
+++ b/README.md
@@ -207,7 +207,7 @@ case. Default is 1000.
 Set spatial reference system/projection. Use 4326 for WGS84 or 3857 for "Google
 Mercator". If you want to use the data for the usual tiled web maps, 3857 is
 probably right. For other uses, especially if you want to re-project to some
-other projection, 4326 is probably right. Other projections are curently not
+other projection, 4326 is probably right. Other projections are currently not
 supported. Default is 4326.
 
     -v, --verbose
diff --git a/cmake/FindOSMPBF.cmake b/cmake/FindOSMPBF.cmake
deleted file mode 100644
index deeebd8..0000000
--- a/cmake/FindOSMPBF.cmake
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# Locate OSMPBF library
-#
-# This module defines
-#  OSMPBF_FOUND        - if false, do not try to link to OSMPBF
-#  OSMPBF_LIBRARIES    - full library path name
-#  OSMPBF_INCLUDE_DIRS - where to find OSMPBF.hpp
-#
-# Note that the expected include convention is
-#  #include <osmpbf/osmpbf.h>
-# and not
-#  #include <osmpbf.h>
-#
-
-find_path(OSMPBF_INCLUDE_DIR osmpbf/osmpbf.h
-    HINTS $ENV{OSMPBF_DIR}
-    PATH_SUFFIXES include
-    PATHS
-        ~/Library/Frameworks
-        /Library/Frameworks
-        /usr/local
-        /usr
-        /opt/local # DarwinPorts
-        /opt
-)
-
-find_library(OSMPBF_LIBRARY
-    NAMES osmpbf
-    HINTS $ENV{OSMPBF_DIR}
-    PATH_SUFFIXES lib64 lib
-    PATHS
-        ~/Library/Frameworks
-        /Library/Frameworks
-        /usr/local
-        /usr
-        /opt/local
-        /opt
-)
-
-# Handle the QUIETLY and REQUIRED arguments and set OSMPBF_FOUND to TRUE if
-# all listed variables are TRUE.
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(OSMPBF DEFAULT_MSG OSMPBF_LIBRARY OSMPBF_INCLUDE_DIR)
-
-# Copy the results to the output variables.
-if(OSMPBF_FOUND)
-    set(OSMPBF_INCLUDE_DIRS ${OSMPBF_INCLUDE_DIR})
-    set(OSMPBF_LIBRARIES ${OSMPBF_LIBRARY})
-endif()
-
diff --git a/cmake/FindOsmium.cmake b/cmake/FindOsmium.cmake
index 1de41a0..bb14071 100644
--- a/cmake/FindOsmium.cmake
+++ b/cmake/FindOsmium.cmake
@@ -110,15 +110,11 @@ endif()
 #----------------------------------------------------------------------
 # Component 'pbf'
 if(Osmium_USE_PBF)
-    find_package(OSMPBF)
-    find_package(Protobuf)
     find_package(ZLIB)
     find_package(Threads)
 
-    if(OSMPBF_FOUND AND PROTOBUF_FOUND AND ZLIB_FOUND AND Threads_FOUND)
+    if(ZLIB_FOUND AND Threads_FOUND)
         list(APPEND OSMIUM_PBF_LIBRARIES
-            ${OSMPBF_LIBRARIES}
-            ${PROTOBUF_LITE_LIBRARY}
             ${ZLIB_LIBRARIES}
             ${CMAKE_THREAD_LIBS_INIT}
         )
@@ -126,8 +122,6 @@ if(Osmium_USE_PBF)
             list(APPEND OSMIUM_PBF_LIBRARIES ws2_32)
         endif()
         list(APPEND OSMIUM_INCLUDE_DIRS
-            ${OSMPBF_INCLUDE_DIRS}
-            ${PROTOBUF_INCLUDE_DIR}
             ${ZLIB_INCLUDE_DIR}
         )
     else()
@@ -325,7 +319,7 @@ endif()
 if(MSVC)
     set(OSMIUM_WARNING_OPTIONS "/W3 /wd4514" CACHE STRING "Recommended warning options for libosmium")
 else()
-    set(OSMIUM_WARNING_OPTIONS "-Wall -Wextra -pedantic -Wredundant-decls -Wdisabled-optimization -Wctor-dtor-privacy -Wnon-virtual-dtor -Woverloaded-virtual -Wsign-promo -Wold-style-cast -Wno-return-type" CACHE STRING "Recommended warning options for libosmium")
+    set(OSMIUM_WARNING_OPTIONS "-Wall -Wextra -pedantic -Wredundant-decls -Wdisabled-optimization -Wctor-dtor-privacy -Wnon-virtual-dtor -Woverloaded-virtual -Wsign-promo -Wold-style-cast" CACHE STRING "Recommended warning options for libosmium")
 endif()
 
 set(OSMIUM_DRACONIC_CLANG_OPTIONS "-Wdocumentation -Wunused-exception-parameter -Wmissing-declarations -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-unused-macros -Wno-exit-time-destructors -Wno-global-constructors -Wno-padded -Wno-switch-enum -Wno-missing-prototypes -Wno-weak-vtables -Wno-cast-align -Wno-float-equal")
diff --git a/man/manpage.template b/man/manpage.template
index e03becc..2f2405d 100644
--- a/man/manpage.template
+++ b/man/manpage.template
@@ -1,7 +1,7 @@
 $if(has-tables)$
 .\"t
 $endif$
-.TH "$title$" "$section$" "$date$" "$footer$" "$header$"
+.TH "$title$" "$section$" "$version$" "$footer$" "$header$"
 $for(header-includes)$
 $header-includes$
 $endfor$
@@ -22,6 +22,7 @@ This is free software: you are free to change and redistribute it.
 There is NO WARRANTY, to the extent permitted by law.
 .SH CONTACT
 .PP
+If you have any questions or want to report a bug, please go to
 http://osmcode.org/contact.html
 .SH AUTHORS
 $for(author)$$author$$sep$; $endfor$.
diff --git a/man/osmcoastline.md b/man/osmcoastline.md
index 275e3a7..a115fb8 100644
--- a/man/osmcoastline.md
+++ b/man/osmcoastline.md
@@ -77,7 +77,15 @@ description of the options below and the README.md for details.
     "Google Mercator". If you want to use the data for the usual tiled web
     maps, 3857 is probably right. For other uses, especially if you want to
     re-project to some other projection, 4326 is probably right. Other
-    projections are curently not supported. Default is 4326.
+    projections are currently not supported. Default is 4326.
+
+-S, --write-segments=FILENAME
+:   Write out all coastline segments to the given file. Segments are
+    connections between two points. The segments are written in an internal
+    format intended for use with the **osmcoastline_segments** program
+    only. The file includes all segments actually in the OSM data and only
+    those. Gaps are (possibly) closed in a later stage of running
+    **osmcoastline**, but those closing segments will not be included.
 
 -v, --verbose
 :   Gives you detailed information on what **osmcoastline** is doing,
@@ -90,6 +98,22 @@ To speed up processing you might want to run the **osmcoastline_filter**
 program first. See its man page for details.
 
 
+# DIAGNOSTICS
+
+**osmcoastline** exits with exit code
+
+0
+  ~ if everything was okay
+1
+  ~ if there were warnings while processing the coastline
+2
+  ~ if there were errors while processing the coastline
+3
+  ~ if there was a fatal error when running the program
+4
+  ~ if there was a problem with the command line arguments.
+
+
 # EXAMPLES
 
 Run **osmcoastline** on a planet file using default options:
@@ -105,6 +129,7 @@ Running **osmcoastline_filter** first:
 # SEE ALSO
 
 * `README.md`
-* **osmcoastline_filter**(1), **osmcoastline_readmeta**(1), **osmcoastline_ways**(1)
+* **osmcoastline_filter**(1), **osmcoastline_readmeta**(1),
+  **osmcoastline_segments**(1), **osmcoastline_ways**(1)
 * [OSMCoastline in OSM wiki](http://wiki.openstreetmap.org/wiki/OSMCoastline)
 
diff --git a/man/osmcoastline_segments.md b/man/osmcoastline_segments.md
new file mode 100644
index 0000000..fc0ab81
--- /dev/null
+++ b/man/osmcoastline_segments.md
@@ -0,0 +1,69 @@
+
+# NAME
+
+osmcoastline_segments - analyze coastline changes from segment files
+
+
+# SYNOPSIS
+
+**osmcoastline_segments** \[*OPTIONS*\] *SEGMENT-FILE1* *SEGMENT-FILE2*
+
+
+# DESCRIPTION
+
+The **osmcoastline** program can write out all segments of the coastline into a
+file (when started with the **-S, --write-segments=FILE** option). This program
+can be used to compare two of those segment files in various ways to detect
+coastline changes between different runs of the **osmcoastline** program.
+
+
+# OPTIONS
+
+-h, --help
+:   Display usage information.
+
+-d, --dump
+:   Dump segment list to stdout in plain text format.
+
+-g, --geom=FILENAME
+:   Write segments to geometry file or database using OGR.
+
+-f, --format=FORMAT
+:   OGR format for writing out geometries.
+
+
+# DIAGNOSTICS
+
+**osmcoastline_segments** exits with exit code
+
+0
+  ~ if the segment files are the same
+1
+  ~ if the segment files are different
+3
+  ~ if there was a fatal error when running the program
+4
+  ~ if there was a problem with the command line arguments.
+
+
+# EXAMPLES
+
+Just return 0 or 1 depending on whether the segments are the same in both files:
+
+    osmcoastline_segments old.segments new.segments
+
+Dump the list of removed and added segments to stdout:
+
+    osmcoastline_segments --dump old.segments new.segments
+
+Create a shapefile with the differences:
+
+    osmcoastline_segments --geom=diff.shp old.segments new.segments
+
+
+# SEE ALSO
+
+* `README.md`
+* **osmcoastline**(1)
+* [OSMCoastline in OSM wiki](http://wiki.openstreetmap.org/wiki/OSMCoastline)
+
diff --git a/simplify_and_split/split_tiles.sql b/simplify_and_split/split_tiles.sql
index 2b15f38..a2f8485 100644
--- a/simplify_and_split/split_tiles.sql
+++ b/simplify_and_split/split_tiles.sql
@@ -13,8 +13,7 @@
 INSERT INTO split_land_polygons (fid, tolerance, min_area, zoom, x, y, geom)
     SELECT p.fid, :tolerance, :min_area, :to_zoom, b.x, b.y, ST_Multi(ST_Intersection(p.geom, b.geom))
         FROM split_land_polygons p, bbox_tiles b
-        WHERE p.geom && b.geom
-          AND ST_Intersects(p.geom, b.geom)
+        WHERE ST_Intersects(p.geom, b.geom)
           AND p.tolerance=:tolerance
           AND p.min_area=:min_area
           AND p.zoom=:from_zoom
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 93f2d6b..907dd1c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -14,6 +14,10 @@ add_executable(osmcoastline_filter osmcoastline_filter.cpp)
 target_link_libraries(osmcoastline_filter ${OSMIUM_IO_LIBRARIES})
 install(TARGETS osmcoastline_filter DESTINATION bin)
 
+add_executable(osmcoastline_segments osmcoastline_segments.cpp srs.cpp)
+target_link_libraries(osmcoastline_segments ${GDAL_LIBRARIES})
+install(TARGETS osmcoastline_segments DESTINATION bin)
+
 add_executable(osmcoastline_ways osmcoastline_ways.cpp osmcoastline.hpp)
 target_link_libraries(osmcoastline_ways ${OSMIUM_IO_LIBRARIES} ${GDAL_LIBRARIES})
 install(TARGETS osmcoastline_ways DESTINATION bin)
diff --git a/src/coastline_ring_collection.cpp b/src/coastline_ring_collection.cpp
index 5cc5823..3101514 100644
--- a/src/coastline_ring_collection.cpp
+++ b/src/coastline_ring_collection.cpp
@@ -237,7 +237,7 @@ std::unique_ptr<OGRLineString> create_ogr_linestring(const osmium::Segment& segm
  * Checks if there are intersections between any coastline segments.
  * Returns the number of intersections and overlaps.
  */
-unsigned int CoastlineRingCollection::check_for_intersections(OutputDatabase& output) {
+unsigned int CoastlineRingCollection::check_for_intersections(OutputDatabase& output, int segments_fd) {
     unsigned int overlaps = 0;
 
     std::vector<osmium::UndirectedSegment> segments;
@@ -249,6 +249,14 @@ unsigned int CoastlineRingCollection::check_for_intersections(OutputDatabase& ou
     if (debug) std::cerr << "Sorting...\n";
     std::sort(segments.begin(), segments.end());
 
+    if (segments_fd >= 0) {
+        if (debug) std::cerr << "Writing segments to file...\n";
+        ssize_t length = segments.size() * sizeof(osmium::UndirectedSegment);
+        if (::write(segments_fd, segments.data(), length) != length) {
+            throw std::runtime_error("Write error");
+        }
+    }
+
     if (debug) std::cerr << "Finding intersections...\n";
     std::vector<osmium::Location> intersections;
     for (auto it1 = segments.cbegin(); it1 != segments.cend()-1; ++it1) {
diff --git a/src/coastline_ring_collection.hpp b/src/coastline_ring_collection.hpp
index 09502a8..21e6f7e 100644
--- a/src/coastline_ring_collection.hpp
+++ b/src/coastline_ring_collection.hpp
@@ -109,7 +109,7 @@ public:
 
     unsigned int output_rings(OutputDatabase& output);
 
-    unsigned int check_for_intersections(OutputDatabase& output);
+    unsigned int check_for_intersections(OutputDatabase& output, int segments_fd);
 
     bool close_antarctica_ring(int epsg);
 
diff --git a/src/options.cpp b/src/options.cpp
index 339c56d..7c11a24 100644
--- a/src/options.cpp
+++ b/src/options.cpp
@@ -45,7 +45,8 @@ Options::Options(int argc, char* argv[]) :
     epsg(4326),
     simplify(false),
     tolerance(0),
-    verbose(false) {
+    verbose(false),
+    segmentfile() {
     static struct option long_options[] = {
         {"bbox-overlap",    required_argument, 0, 'b'},
         {"close-distance",  required_argument, 0, 'c'},
@@ -59,6 +60,7 @@ Options::Options(int argc, char* argv[]) :
         {"output-rings",          no_argument, 0, 'r'},
         {"overwrite",             no_argument, 0, 'f'},
         {"srs",             required_argument, 0, 's'},
+        {"write-segments",  required_argument, 0, 'S'},
         {"verbose",               no_argument, 0, 'v'},
         {0, 0, 0, 0}
     };
@@ -123,6 +125,9 @@ Options::Options(int argc, char* argv[]) :
             case 's':
                 epsg = get_epsg(optarg);
                 break;
+            case 'S':
+                segmentfile = optarg;
+                break;
             case 'v':
                 verbose = true;
                 break;
@@ -190,6 +195,7 @@ void Options::print_help() const {
               << "                             - Which polygons to write out (default: land)\n"
               << "  -r, --output-rings         - Output rings to database file\n"
               << "  -s, --srs=EPSGCODE         - Set SRS (4326 for WGS84 (default) or 3857)\n"
+              << "  -S, --write-segments=FILE  - Write segments to given file\n"
               << "  -v, --verbose              - Verbose output\n"
               << "\n";
 }
diff --git a/src/options.hpp b/src/options.hpp
index acfd094..f6d8dc6 100644
--- a/src/options.hpp
+++ b/src/options.hpp
@@ -92,6 +92,9 @@ public:
     /// Verbose output?
     bool verbose;
 
+    /// Name of optional segment file
+    std::string segmentfile;
+
     Options(int argc, char* argv[]);
 
 private:
diff --git a/src/osmcoastline.cpp b/src/osmcoastline.cpp
index c63bcfd..5f8adcf 100644
--- a/src/osmcoastline.cpp
+++ b/src/osmcoastline.cpp
@@ -161,6 +161,17 @@ int main(int argc, char *argv[]) {
         exit(return_code_fatal);
     }
 
+    // Optionally set up segments file
+    int segments_fd = -1;
+    if (!options.segmentfile.empty()) {
+        vout << "Writing segments to file '" << options.segmentfile << "' (because you told me to with --write-segments/-S option).\n";
+        segments_fd = ::open(options.segmentfile.c_str(), O_WRONLY | O_CREAT, 0666);
+        if (segments_fd == -1) {
+            std::cerr << "Couldn't open file '" << options.segmentfile << "' (" << strerror(errno) << ")\n";
+            exit(return_code_fatal);
+        }
+    }
+
     // Set up output database.
     vout << "Writing to output database '" << options.output_database << "'. (Was set with the --output-database/-o option.)\n";
     if (options.overwrite_output) {
@@ -220,7 +231,11 @@ int main(int argc, char *argv[]) {
     output_database.set_options(options);
 
     vout << "Check line segments for intersections and overlaps...\n";
-    warnings += coastline_rings.check_for_intersections(output_database);
+    warnings += coastline_rings.check_for_intersections(output_database, segments_fd);
+
+    if (segments_fd != -1) {
+        ::close(segments_fd);
+    }
 
     vout << "Trying to close Antarctica ring...\n";
     if (coastline_rings.close_antarctica_ring(options.epsg)) {
@@ -311,8 +326,6 @@ int main(int argc, char *argv[]) {
     std::cout << "There were " << warnings << " warnings.\n";
     std::cout << "There were " << errors << " errors.\n";
 
-    google::protobuf::ShutdownProtobufLibrary();
-
     if (errors || warnings > max_warnings) {
         return return_code_error;
     } else if (warnings) {
diff --git a/src/osmcoastline_filter.cpp b/src/osmcoastline_filter.cpp
index 579d5a0..a89bfec 100644
--- a/src/osmcoastline_filter.cpp
+++ b/src/osmcoastline_filter.cpp
@@ -136,7 +136,5 @@ int main(int argc, char* argv[]) {
         std::cerr << "io error: " << e.what() << "'\n";
         exit(return_code_fatal);
     }
-
-    google::protobuf::ShutdownProtobufLibrary();
 }
 
diff --git a/src/osmcoastline_segments.cpp b/src/osmcoastline_segments.cpp
new file mode 100644
index 0000000..1702960
--- /dev/null
+++ b/src/osmcoastline_segments.cpp
@@ -0,0 +1,214 @@
+/*
+
+  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 <algorithm>
+#include <cassert>
+#include <fcntl.h>
+#include <getopt.h>
+#include <iostream>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <osmium/osm/undirected_segment.hpp>
+#include <osmium/util/memory_mapping.hpp>
+
+#include "ogr_include.hpp"
+#include "osmcoastline.hpp"
+#include "srs.hpp"
+
+typedef std::vector<osmium::UndirectedSegment> segvec;
+
+class InputFile {
+
+    std::string m_filename;
+    int m_fd;
+
+public:
+
+    InputFile(const std::string& filename) :
+        m_filename(filename),
+        m_fd(::open(filename.c_str(), O_RDONLY)) {
+        if (m_fd == -1) {
+            throw std::system_error(errno, std::system_category(), std::string("Opening '") + filename + "' failed");
+        }
+    }
+
+    int fd() const {
+        return m_fd;
+    }
+
+    size_t size() const {
+        struct stat s;
+        if (::fstat(m_fd, &s) != 0) {
+            throw std::system_error(errno, std::system_category(), std::string("Can't get file size for '") + m_filename + "'");
+        }
+        return size_t(s.st_size);
+    }
+
+}; // class InputFile
+
+void print_help() {
+}
+
+void add_segment(OGRLayer* layer, int change, const osmium::UndirectedSegment& segment) {
+    OGRFeature* feature = OGRFeature::CreateFeature(layer->GetLayerDefn());
+
+    auto linestring = 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);
+}
+
+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);
+    }
+
+    layer->StartTransaction();
+
+    for (const auto& segment : removed_segments) {
+        add_segment(layer, 0, segment);
+    }
+
+    for (const auto& segment : added_segments) {
+        add_segment(layer, 1, segment);
+    }
+
+    layer->CommitTransaction();
+}
+
+int main(int argc, char *argv[]) {
+    bool dump = false;
+    std::string format = "ESRI Shapefile";
+    std::string geom;
+
+    static struct option long_options[] = {
+        {"dump",         no_argument, 0, 'd'},
+        {"format", required_argument, 0, 'f'},
+        {"geom",   required_argument, 0, 'g'},
+        {"help",         no_argument, 0, 'h'},
+        {0, 0, 0, 0}
+    };
+
+    while (1) {
+        int c = getopt_long(argc, argv, "df:g:h", long_options, 0);
+        if (c == -1)
+            break;
+
+        switch (c) {
+            case 'd':
+                dump = true;
+                break;
+            case 'f':
+                format = optarg;
+                break;
+            case 'g':
+                geom = optarg;
+                break;
+            case 'h': {
+                std::cout << "Usage: " << argv[0] << " [OPTIONS] SEGFILE1 SEGFILE2\n";
+                print_help();
+                exit(return_code_ok);
+            }
+            default:
+                break;
+        }
+    }
+
+    if (optind != argc - 2) {
+        std::cerr << "Usage: " << argv[0] << " [OPTIONS] SEGFILE1 SEGFILE2\n";
+        exit(return_code_cmdline);
+    }
+
+    segvec removed_segments;
+    segvec added_segments;
+
+    try {
+        InputFile file1(argv[optind]);
+        InputFile file2(argv[optind+1]);
+
+        osmium::util::TypedMemoryMapping<osmium::UndirectedSegment> m1(file1.size() / sizeof(osmium::UndirectedSegment), false, file1.fd());
+        osmium::util::TypedMemoryMapping<osmium::UndirectedSegment> m2(file2.size() / sizeof(osmium::UndirectedSegment), false, file2.fd());
+
+        std::set_difference(m1.cbegin(), m1.cend(), m2.cbegin(), m2.cend(), std::back_inserter(removed_segments));
+        std::set_difference(m2.cbegin(), m2.cend(), m1.cbegin(), m1.cend(), std::back_inserter(added_segments));
+    } catch (std::runtime_error& e) {
+        std::cerr << e.what() << "\n";
+        exit(return_code_fatal);
+    }
+
+    if (dump) {
+        std::cout << "Removed:\n";
+        for (const auto& segment : removed_segments) {
+            std::cout << "  " << segment << "\n";
+        }
+
+        std::cout << "Added:\n";
+        for (const auto& segment : added_segments) {
+            std::cout << "  " << segment << "\n";
+        }
+    } else if (!geom.empty()) {
+        output_ogr(geom, format, removed_segments, added_segments);
+    }
+
+    return (removed_segments.empty() && added_segments.empty()) ? 0 : 1;
+}
+
diff --git a/src/osmcoastline_ways.cpp b/src/osmcoastline_ways.cpp
index 35b97ab..6dcfe89 100644
--- a/src/osmcoastline_ways.cpp
+++ b/src/osmcoastline_ways.cpp
@@ -167,7 +167,5 @@ int main(int argc, char* argv[]) {
     reader2.close();
 
     std::cerr << "Sum of way lengths: " << std::fixed << (coastline_ways_handler.sum_length() / 1000) << "km\n";
-
-    google::protobuf::ShutdownProtobufLibrary();
 }
 

-- 
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