[osmium-contrib] 01/02: Imported Upstream version 0.0~20150306-0c4f263

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Fri Mar 6 17:10:05 UTC 2015


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

sebastic pushed a commit to branch master
in repository osmium-contrib.

commit 3b146944868cfc09aae5646729b82cea17716a9e
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Fri Mar 6 16:28:05 2015 +0100

    Imported Upstream version 0.0~20150306-0c4f263
---
 .gitignore                          |   2 +
 .travis.yml                         |  43 +++++
 CMakeLists.txt                      |  44 +++++
 Makefile                            |  18 ++
 README.md                           |  41 +++++
 amenity_list/.gitignore             |   1 +
 amenity_list/CMakeLists.txt         |  24 +++
 amenity_list/Makefile               |  12 ++
 amenity_list/README.md              |  47 +++++
 amenity_list/amenity_list.cpp       |  84 +++++++++
 cmake/CppcheckTarget.cmake          |  25 +++
 cmake/FindOSMPBF.cmake              |  50 ++++++
 cmake/FindOsmium.cmake              | 340 ++++++++++++++++++++++++++++++++++++
 cmake/common.cmake                  |  90 ++++++++++
 export_to_wkt/.gitignore            |   1 +
 export_to_wkt/CMakeLists.txt        |  24 +++
 export_to_wkt/Makefile              |  12 ++
 export_to_wkt/README.md             |  45 +++++
 export_to_wkt/export_to_wkt.cpp     |  77 ++++++++
 mapolution/.gitignore               |   3 +
 mapolution/CMakeLists.txt           |  31 ++++
 mapolution/Makefile                 |  12 ++
 mapolution/README.md                |  70 ++++++++
 mapolution/cmdline_options.cpp      | 105 +++++++++++
 mapolution/cmdline_options.hpp      |  35 ++++
 mapolution/gdalcpp.hpp              | 221 +++++++++++++++++++++++
 mapolution/geom_handler.hpp         |  63 +++++++
 mapolution/handlers/buildings.hpp   |  43 +++++
 mapolution/handlers/restaurants.hpp |  59 +++++++
 mapolution/handlers/roads.hpp       |  42 +++++
 mapolution/main.cpp                 | 253 +++++++++++++++++++++++++++
 mapolution/rasterize.sh             |  40 +++++
 node_density/.gitignore             |   3 +
 node_density/CMakeLists.txt         |  24 +++
 node_density/Makefile               |  12 ++
 node_density/README.md              | 109 ++++++++++++
 node_density/cmdline_options.cpp    | 125 +++++++++++++
 node_density/cmdline_options.hpp    |  35 ++++
 node_density/colors.txt             |   5 +
 node_density/example.qlr            |  49 ++++++
 node_density/main.cpp               | 197 +++++++++++++++++++++
 pub_names/.gitignore                |   1 +
 pub_names/CMakeLists.txt            |  24 +++
 pub_names/Makefile                  |  12 ++
 pub_names/README.md                 |  45 +++++
 pub_names/pub_names.cpp             |  46 +++++
 road_length/.gitignore              |   1 +
 road_length/CMakeLists.txt          |  24 +++
 road_length/Makefile                |  12 ++
 road_length/README.md               |  46 +++++
 road_length/road_length.cpp         |  45 +++++
 51 files changed, 2772 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fdb2c6c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.*.swp
+build*
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..f5dffb1
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,43 @@
+language: cpp
+
+compiler:
+ - gcc
+ - clang
+
+env:
+ - CONFIGURATION=Dev
+ - CONFIGURATION=Release
+
+before_install:
+ # we need at least g++-4.8 for c++11 features
+ - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test
+ - sudo apt-get update --yes --quiet
+
+install:
+ # upgrade compilers
+ - sudo apt-get install --yes gcc-4.8 g++-4.8
+ # make sure 'cpp' is the just installed current one
+ - sudo rm /usr/bin/cpp
+ - sudo ln -s /usr/bin/cpp-4.8 /usr/bin/cpp
+ # upgrade libosmium dependencies
+ - sudo apt-get install --yes make libboost1.48-dev libboost-program-options1.48-dev libboost-filesystem1.48-dev libsparsehash-dev libgdal-dev libproj-dev libprotobuf-dev protobuf-compiler
+ - cd ..
+ - git clone https://github.com/osmcode/libosmium.git
+ # OSMPBF is too old, install from git
+ #- sudo apt-get install --yes libosmpbf-dev
+ - git clone https://github.com/scrosby/OSM-binary.git
+ - cd OSM-binary/src
+ - make
+ - sudo make install
+
+#before_script:
+# - true
+
+script:
+ - cd $TRAVIS_BUILD_DIR
+ - if [ "${CXX}" = 'g++' ]; then export CXX=g++-4.8; fi;
+ - mkdir build
+ - cd build
+ - cmake -LA -DCMAKE_BUILD_TYPE=${CONFIGURATION} ..
+ - make VERBOSE=1
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..6e04c7e
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,44 @@
+#-----------------------------------------------------------------------------
+#
+#  CMake Config
+#
+#  Osmium-contrib
+#
+#-----------------------------------------------------------------------------
+
+cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+
+
+#-----------------------------------------------------------------------------
+project(osmium-contrib)
+
+include(common)
+
+find_package(Boost REQUIRED COMPONENTS program_options system filesystem)
+include_directories(${Boost_INCLUDE_DIRS})
+
+find_package(Osmium REQUIRED COMPONENTS io gdal proj sparsehash)
+include_directories(${OSMIUM_INCLUDE_DIRS})
+
+
+#-----------------------------------------------------------------------------
+#
+#  Configure all subprojects on their own
+#
+#-----------------------------------------------------------------------------
+macro(configure_subproject _subproject)
+    file(GLOB SOURCES ${_subproject}/*.cpp ${_subproject}/*.hpp)
+    add_executable(${_subproject} ${SOURCES})
+    target_link_libraries(${_subproject} ${Boost_LIBRARIES} ${OSMIUM_LIBRARIES})
+endmacro()
+
+configure_subproject(amenity_list)
+configure_subproject(pub_names)
+configure_subproject(road_length)
+configure_subproject(export_to_wkt)
+configure_subproject(node_density)
+configure_subproject(mapolution)
+
+
+#-----------------------------------------------------------------------------
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..39bcc83
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,18 @@
+
+PROJECTS := `find . -mindepth 2 -name Makefile | xargs dirname | cut -c3-`
+
+all:
+	for i in $(PROJECTS); do \
+	    $(MAKE) -C $$i; \
+	done
+
+clean:
+	for i in $(PROJECTS); do \
+	    $(MAKE) -C $$i clean; \
+	done
+
+distclean:
+	for i in $(PROJECTS); do \
+	    rm -fr $$i/build; \
+	done
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9dc720a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,41 @@
+
+# Osmium Contrib
+
+This repository contains a mixed bunch of more or less useful examples of how
+to work with the Osmium library.
+
+You have to set up Osmium first. See http://osmcode.org/libosmium .
+
+
+## License
+
+All contributions have their own licenses.
+
+
+## Building
+
+This will work easiest if you have Osmium installed in your normal include path
+or if the libosmium git repository is checked out in the same directory as the
+"osmium-contrib" repository.
+
+Osmium-contrib uses CMake for its builds. For Unix/Linux systems a simple
+Makefile wrapper is provided to make the build even easier.
+
+### Building all projects
+
+In the main directory type `make`. Results will be in the `build` subdirectory.
+
+Or you can go the long route explicitly calling CMake as follows:
+
+```
+mkdir build
+cd build
+cmake ..
+make
+```
+
+### Building a single project
+
+You can build each project by itself by changing into its directory and calling
+`make` or `cmake` as described above.
+
diff --git a/amenity_list/.gitignore b/amenity_list/.gitignore
new file mode 100644
index 0000000..e637b82
--- /dev/null
+++ b/amenity_list/.gitignore
@@ -0,0 +1 @@
+amenity_list
diff --git a/amenity_list/CMakeLists.txt b/amenity_list/CMakeLists.txt
new file mode 100644
index 0000000..034e06b
--- /dev/null
+++ b/amenity_list/CMakeLists.txt
@@ -0,0 +1,24 @@
+#----------------------------------------------------------------------
+#
+#  Single example osmium-contrib CMakeLists.txt
+#
+#----------------------------------------------------------------------
+project(osmium-amenity-list)
+
+cmake_minimum_required(VERSION 2.8.5)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake")
+
+find_package(Boost REQUIRED)
+include_directories(${Boost_INCLUDE_DIRS})
+
+find_package(Osmium REQUIRED COMPONENTS io sparsehash)
+include_directories(${OSMIUM_INCLUDE_DIRS})
+
+include(common)
+
+#----------------------------------------------------------------------
+
+set(PROG amenity_list)
+file(GLOB SOURCES *.cpp *.hpp)
+add_executable(${PROG} ${SOURCES})
+target_link_libraries(${PROG} ${Boost_LIBRARIES} ${OSMIUM_LIBRARIES})
diff --git a/amenity_list/Makefile b/amenity_list/Makefile
new file mode 100644
index 0000000..8f43712
--- /dev/null
+++ b/amenity_list/Makefile
@@ -0,0 +1,12 @@
+
+all:
+	mkdir -p build && cd build && cmake .. && $(MAKE)
+
+clean:
+	if test -d build; then cd build && $(MAKE) clean; fi
+
+distclean:
+	rm -fr build
+
+.PHONY: clean distclean
+
diff --git a/amenity_list/README.md b/amenity_list/README.md
new file mode 100644
index 0000000..cee67e1
--- /dev/null
+++ b/amenity_list/README.md
@@ -0,0 +1,47 @@
+
+# Amenity List
+
+Prints a list of all amenities in the file with type, name and coordinates.
+For amenities that are mapped as areas the centroid will be printed as
+coordinate.
+
+
+## Prerequisites
+
+You'll need libosmium (http://osmcode.org/libosmium) and its dependencies
+installed first.
+
+
+## Building
+
+Osmium-contrib uses CMake for its builds. For Unix/Linux systems a simple
+Makefile wrapper is provided to make the build even easier.
+
+To build just type `make`. Results will be in the `build` subdirectory.
+
+Or you can go the long route explicitly calling CMake as follows:
+
+```
+mkdir build
+cd build
+cmake ..
+make
+```
+
+
+## Running
+
+Run the program with an OSM file as its only argument:
+
+`amenity_list switzerland.osm.pbf`
+
+
+## License
+
+This program is released into the Public Domain.
+
+
+## Author
+
+Jochen Topf (http://jochentopf.com/)
+
diff --git a/amenity_list/amenity_list.cpp b/amenity_list/amenity_list.cpp
new file mode 100644
index 0000000..afcee5d
--- /dev/null
+++ b/amenity_list/amenity_list.cpp
@@ -0,0 +1,84 @@
+
+// The code in this file is released into the Public Domain.
+
+#include <cstdio>
+#include <iostream>
+
+#include <osmium/index/map/sparse_mem_array.hpp>
+#include <osmium/handler/node_locations_for_ways.hpp>
+typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
+typedef osmium::handler::NodeLocationsForWays<index_type> location_handler_type;
+
+#include <osmium/area/assembler.hpp>
+#include <osmium/area/multipolygon_collector.hpp>
+#include <osmium/io/any_input.hpp>
+#include <osmium/visitor.hpp>
+
+class AmenityHandler : public osmium::handler::Handler {
+
+    void print_amenity(const char* type, const char* name, double x, double y) {
+        printf("%8.4f,%8.4f %-15s %s\n", x, y, type, name ? name : "");
+    }
+
+public:
+
+    void node(const osmium::Node& node) {
+        const char* amenity = node.tags()["amenity"];
+        if (amenity) {
+            print_amenity(amenity, node.tags()["name"],
+                          node.location().lon(), node.location().lat());
+        }
+    }
+
+    void area(const osmium::Area& area) {
+        if (area.cbegin<osmium::OuterRing>() == area.cend<osmium::OuterRing>()) {
+            return;
+        }
+        const char* amenity = area.tags()["amenity"];
+        if (amenity) {
+            // simply use the centroid of the first outer ring
+            const osmium::OuterRing &ring = *area.cbegin<osmium::OuterRing>();
+            double x = 0;
+            double y = 0;
+            for (const auto& l : ring) {
+                x += l.lon();
+                y += l.lat();
+            }
+            x /= ring.size();
+            y /= ring.size();
+
+            print_amenity(amenity, area.tags()["name"], x, y);
+        }
+    }
+
+}; // class AmenityHandler
+
+int main(int argc, char* argv[]) {
+    if (argc != 2) {
+        std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
+        exit(1);
+    }
+
+    osmium::area::Assembler::config_type assembler_config;
+    osmium::area::MultipolygonCollector<osmium::area::Assembler> collector(assembler_config);
+
+    std::cerr << "Pass 1...\n";
+    osmium::io::Reader reader1(argv[1]);
+    collector.read_relations(reader1);
+    reader1.close();
+    std::cerr << "Pass 1 done\n";
+
+    index_type index;
+    location_handler_type location_handler(index);
+    location_handler.ignore_errors();
+
+    AmenityHandler data_handler;
+
+    std::cerr << "Pass 2...\n";
+    osmium::io::Reader reader2(argv[1]);
+
+    osmium::apply(reader2, location_handler, data_handler, collector.handler([&data_handler](const osmium::memory::Buffer& area_buffer) {
+        osmium::apply(area_buffer, data_handler);
+    }));
+}
+
diff --git a/cmake/CppcheckTarget.cmake b/cmake/CppcheckTarget.cmake
new file mode 100644
index 0000000..82be792
--- /dev/null
+++ b/cmake/CppcheckTarget.cmake
@@ -0,0 +1,25 @@
+#----------------------------------------------------------------------
+#
+#  Optional "cppcheck" target that checks C++ code
+#
+#----------------------------------------------------------------------
+function(add_cppcheck_target _var)
+
+  message(STATUS "Looking for cppcheck")
+  find_program(CPPCHECK cppcheck)
+
+  if(CPPCHECK)
+    message(STATUS "Looking for cppcheck - found")
+    set(CPPCHECK_OPTIONS --enable=warning,style,performance,portability,information,missingInclude)
+
+    # cpp doesn't find system includes for some reason, suppress that report
+    set(CPPCHECK_OPTIONS ${CPPCHECK_OPTIONS} --suppress=missingIncludeSystem)
+
+    file(GLOB SOURCES ${_var})
+    add_custom_target(cppcheck ${CPPCHECK} --std=c++11 ${CPPCHECK_OPTIONS} ${SOURCES})
+  else()
+    message(STATUS "Looking for cppcheck - not found")
+    message(STATUS "  Make target cppcheck not available")
+  endif(CPPCHECK)
+
+endfunction()
diff --git a/cmake/FindOSMPBF.cmake b/cmake/FindOSMPBF.cmake
new file mode 100644
index 0000000..deeebd8
--- /dev/null
+++ b/cmake/FindOSMPBF.cmake
@@ -0,0 +1,50 @@
+#
+# 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
new file mode 100644
index 0000000..1de41a0
--- /dev/null
+++ b/cmake/FindOsmium.cmake
@@ -0,0 +1,340 @@
+#----------------------------------------------------------------------
+#
+#  FindOsmium.cmake
+#
+#  Find the Libosmium headers and, optionally, several components needed for
+#  different Libosmium functions.
+#
+#----------------------------------------------------------------------
+#
+#  Usage:
+#
+#    Copy this file somewhere into your project directory, where cmake can
+#    find it. Usually this will be a directory called "cmake" which you can
+#    add to the CMake module search path with the following line in your
+#    CMakeLists.txt:
+#
+#      list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+#
+#    Then add the following in your CMakeLists.txt:
+#
+#      find_package(Osmium REQUIRED COMPONENTS <XXX>)
+#      include_directories(${OSMIUM_INCLUDE_DIRS})
+#
+#    For the <XXX> substitute a space separated list of one or more of the
+#    following components:
+#
+#      pbf        - include libraries needed for PBF input and output
+#      xml        - include libraries needed for XML input and output
+#      io         - include libraries needed for any type of input/output
+#      geos       - include if you want to use any of the GEOS functions
+#      gdal       - include if you want to use any of the OGR functions
+#      proj       - include if you want to use any of the Proj.4 functions
+#      sparsehash - include if you use the sparsehash index
+#
+#    You can check for success with something like this:
+#
+#      if(NOT OSMIUM_FOUND)
+#          message(WARNING "Libosmium not found!\n")
+#      endif()
+#
+#----------------------------------------------------------------------
+#
+#  Variables:
+#
+#    OSMIUM_FOUND         - True if Osmium found.
+#    OSMIUM_INCLUDE_DIRS  - Where to find include files.
+#    OSMIUM_XML_LIBRARIES - Libraries needed for XML I/O.
+#    OSMIUM_PBF_LIBRARIES - Libraries needed for PBF I/O.
+#    OSMIUM_IO_LIBRARIES  - Libraries needed for XML or PBF I/O.
+#    OSMIUM_LIBRARIES     - All libraries Osmium uses somewhere.
+#
+#----------------------------------------------------------------------
+
+# Look for the header file.
+find_path(OSMIUM_INCLUDE_DIR osmium/osm.hpp
+    PATH_SUFFIXES include
+    PATHS
+        ../libosmium
+        ../../libosmium
+        libosmium
+        ~/Library/Frameworks
+        /Library/Frameworks
+        /usr/local
+        /usr/
+        /opt/local # DarwinPorts
+        /opt
+)
+
+# Handle the QUIETLY and REQUIRED arguments and set OSMIUM_FOUND to TRUE if
+# all listed variables are TRUE.
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(OSMIUM REQUIRED_VARS OSMIUM_INCLUDE_DIR)
+
+# Copy the results to the output variables.
+if(OSMIUM_FOUND)
+    set(OSMIUM_INCLUDE_DIRS ${OSMIUM_INCLUDE_DIR})
+else()
+    set(OSMIUM_INCLUDE_DIRS "")
+endif()
+
+if(Osmium_FIND_REQUIRED AND NOT OSMIUM_FOUND)
+    message(FATAL_ERROR "Can not find libosmium headers, please install them or configure the paths")
+endif()
+
+#----------------------------------------------------------------------
+#
+#  Check for optional components
+#
+#----------------------------------------------------------------------
+if(Osmium_FIND_COMPONENTS)
+    foreach(_component ${Osmium_FIND_COMPONENTS})
+        string(TOUPPER ${_component} _component_uppercase)
+        set(Osmium_USE_${_component_uppercase} TRUE)
+    endforeach()
+endif()
+
+#----------------------------------------------------------------------
+# Component 'io' is an alias for 'pbf' and 'xml'
+if(Osmium_USE_IO)
+    set(Osmium_USE_PBF TRUE)
+    set(Osmium_USE_XML TRUE)
+endif()
+
+#----------------------------------------------------------------------
+# Component 'ogr' is an alias for 'gdal'
+if(Osmium_USE_OGR)
+    set(Osmium_USE_GDAL TRUE)
+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)
+        list(APPEND OSMIUM_PBF_LIBRARIES
+            ${OSMPBF_LIBRARIES}
+            ${PROTOBUF_LITE_LIBRARY}
+            ${ZLIB_LIBRARIES}
+            ${CMAKE_THREAD_LIBS_INIT}
+        )
+        if(WIN32)
+            list(APPEND OSMIUM_PBF_LIBRARIES ws2_32)
+        endif()
+        list(APPEND OSMIUM_INCLUDE_DIRS
+            ${OSMPBF_INCLUDE_DIRS}
+            ${PROTOBUF_INCLUDE_DIR}
+            ${ZLIB_INCLUDE_DIR}
+        )
+    else()
+        set(_missing_libraries 1)
+        message(WARNING "Osmium: Can not find some libraries for PBF input/output, please install them or configure the paths.")
+    endif()
+endif()
+
+#----------------------------------------------------------------------
+# Component 'xml'
+if(Osmium_USE_XML)
+    find_package(EXPAT)
+    find_package(BZip2)
+    find_package(ZLIB)
+    find_package(Threads)
+
+    if(EXPAT_FOUND AND BZIP2_FOUND AND ZLIB_FOUND AND Threads_FOUND)
+        list(APPEND OSMIUM_XML_LIBRARIES
+            ${EXPAT_LIBRARIES}
+            ${BZIP2_LIBRARIES}
+            ${ZLIB_LIBRARIES}
+            ${CMAKE_THREAD_LIBS_INIT}
+        )
+        list(APPEND OSMIUM_INCLUDE_DIRS
+            ${EXPAT_INCLUDE_DIR}
+            ${BZIP2_INCLUDE_DIR}
+            ${ZLIB_INCLUDE_DIR}
+        )
+    else()
+        set(_missing_libraries 1)
+        message(WARNING "Osmium: Can not find some libraries for XML input/output, please install them or configure the paths.")
+    endif()
+endif()
+
+#----------------------------------------------------------------------
+list(APPEND OSMIUM_IO_LIBRARIES
+    ${OSMIUM_PBF_LIBRARIES}
+    ${OSMIUM_XML_LIBRARIES}
+)
+
+list(APPEND OSMIUM_LIBRARIES
+    ${OSMIUM_IO_LIBRARIES}
+)
+
+#----------------------------------------------------------------------
+# Component 'geos'
+if(Osmium_USE_GEOS)
+    find_path(GEOS_INCLUDE_DIR geos/geom.h)
+    find_library(GEOS_LIBRARY NAMES geos)
+
+    if(GEOS_INCLUDE_DIR AND GEOS_LIBRARY)
+        SET(GEOS_FOUND 1)
+        list(APPEND OSMIUM_LIBRARIES ${GEOS_LIBRARY})
+        list(APPEND OSMIUM_INCLUDE_DIRS ${GEOS_INCLUDE_DIR})
+    else()
+        set(_missing_libraries 1)
+        message(WARNING "Osmium: GEOS library is required but not found, please install it or configure the paths.")
+    endif()
+endif()
+
+#----------------------------------------------------------------------
+# Component 'gdal' (alias 'ogr')
+if(Osmium_USE_GDAL)
+    find_package(GDAL)
+
+    if(GDAL_FOUND)
+        list(APPEND OSMIUM_LIBRARIES ${GDAL_LIBRARIES})
+        list(APPEND OSMIUM_INCLUDE_DIRS ${GDAL_INCLUDE_DIRS})
+    else()
+        set(_missing_libraries 1)
+        message(WARNING "Osmium: GDAL library is required but not found, please install it or configure the paths.")
+    endif()
+endif()
+
+#----------------------------------------------------------------------
+# Component 'proj'
+if(Osmium_USE_PROJ)
+    find_path(PROJ_INCLUDE_DIR proj_api.h)
+    find_library(PROJ_LIBRARY NAMES proj)
+
+    if(PROJ_INCLUDE_DIR AND PROJ_LIBRARY)
+        set(PROJ_FOUND 1)
+        list(APPEND OSMIUM_LIBRARIES ${PROJ_LIBRARY})
+        list(APPEND OSMIUM_INCLUDE_DIRS ${PROJ_INCLUDE_DIR})
+    else()
+        set(_missing_libraries 1)
+        message(WARNING "Osmium: PROJ.4 library is required but not found, please install it or configure the paths.")
+    endif()
+endif()
+
+#----------------------------------------------------------------------
+# Component 'sparsehash'
+if(Osmium_USE_SPARSEHASH)
+    find_path(SPARSEHASH_INCLUDE_DIR google/sparsetable)
+
+    if(SPARSEHASH_INCLUDE_DIR)
+        # Find size of sparsetable::size_type. This does not work on older
+        # CMake versions because they can do this check only in C, not in C++.
+        include(CheckTypeSize)
+        set(CMAKE_REQUIRED_INCLUDES ${SPARSEHASH_INCLUDE_DIR})
+        set(CMAKE_EXTRA_INCLUDE_FILES "google/sparsetable")
+        check_type_size("google::sparsetable<int>::size_type" SPARSETABLE_SIZE_TYPE LANGUAGE CXX)
+        set(CMAKE_EXTRA_INCLUDE_FILES)
+        set(CMAKE_REQUIRED_INCLUDES)
+
+        # Falling back to checking size_t if google::sparsetable<int>::size_type
+        # could not be checked.
+        if(SPARSETABLE_SIZE_TYPE STREQUAL "")
+            check_type_size("void*" VOID_PTR_SIZE)
+            set(SPARSETABLE_SIZE_TYPE ${VOID_PTR_SIZE})
+        endif()
+
+        # Sparsetable::size_type must be at least 8 bytes (64bit), otherwise
+        # OSM object IDs will not fit.
+        if(SPARSETABLE_SIZE_TYPE GREATER 7)
+            set(SPARSEHASH_FOUND 1)
+            add_definitions(-DOSMIUM_WITH_SPARSEHASH=${SPARSEHASH_FOUND})
+            list(APPEND OSMIUM_INCLUDE_DIRS ${SPARSEHASH_INCLUDE_DIR})
+        else()
+            message(WARNING "Osmium: Disabled Google SparseHash library on 32bit system (size_type=${SPARSETABLE_SIZE_TYPE}).")
+        endif()
+    else()
+        set(_missing_libraries 1)
+        message(WARNING "Osmium: Google SparseHash library is required but not found, please install it or configure the paths.")
+    endif()
+endif()
+
+#----------------------------------------------------------------------
+
+list(REMOVE_DUPLICATES OSMIUM_INCLUDE_DIRS)
+
+if(OSMIUM_XML_LIBRARIES)
+    list(REMOVE_DUPLICATES OSMIUM_XML_LIBRARIES)
+endif()
+
+if(OSMIUM_PBF_LIBRARIES)
+    list(REMOVE_DUPLICATES OSMIUM_PBF_LIBRARIES)
+endif()
+
+if(OSMIUM_IO_LIBRARIES)
+    list(REMOVE_DUPLICATES OSMIUM_IO_LIBRARIES)
+endif()
+
+if(OSMIUM_LIBRARIES)
+    list(REMOVE_DUPLICATES OSMIUM_LIBRARIES)
+endif()
+
+#----------------------------------------------------------------------
+#
+#  Check that all required libraries are available
+#
+#----------------------------------------------------------------------
+if(Osmium_FIND_REQUIRED AND _missing_libraries)
+    message(FATAL_ERROR "Required library or libraries missing. Aborting.")
+endif()
+
+#----------------------------------------------------------------------
+#
+#  Add compiler flags
+#
+#----------------------------------------------------------------------
+add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64)
+
+if(MSVC)
+    add_definitions(-wd4996)
+
+    # Disable warning C4068: "unknown pragma" because we want it to ignore
+    # pragmas for other compilers.
+    add_definitions(-wd4068)
+
+    # Disable warning C4715: "not all control paths return a value" because
+    # it generates too many false positives.
+    add_definitions(-wd4715)
+
+    # Disable warning C4351: new behavior: elements of array '...' will be
+    # default initialized. The new behaviour is correct and we don't support
+    # old compilers anyway.
+    add_definitions(-wd4351)
+
+    add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_WARNINGS)
+endif()
+
+if(APPLE)
+# following only available from cmake 2.8.12:
+#   add_compile_options(-stdlib=libc++)
+# so using this instead:
+    add_definitions(-stdlib=libc++)
+    set(LDFLAGS ${LDFLAGS} -stdlib=libc++)
+endif()
+
+#----------------------------------------------------------------------
+
+# This is a set of recommended warning options that can be added when compiling
+# libosmium code.
+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")
+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")
+
+if(Osmium_DEBUG)
+    message(STATUS "OSMIUM_XML_LIBRARIES=" ${OSMIUM_XML_LIBRARIES})
+    message(STATUS "OSMIUM_PBF_LIBRARIES=" ${OSMIUM_PBF_LIBRARIES})
+    message(STATUS "OSMIUM_IO_LIBRARIES=" ${OSMIUM_IO_LIBRARIES})
+    message(STATUS "OSMIUM_LIBRARIES=" ${OSMIUM_LIBRARIES})
+    message(STATUS "OSMIUM_INCLUDE_DIRS=" ${OSMIUM_INCLUDE_DIRS})
+endif()
+
diff --git a/cmake/common.cmake b/cmake/common.cmake
new file mode 100644
index 0000000..e8b2205
--- /dev/null
+++ b/cmake/common.cmake
@@ -0,0 +1,90 @@
+#-----------------------------------------------------------------------------
+#
+#  CMake config used in all projects in this repository.
+#
+#-----------------------------------------------------------------------------
+
+include(CppcheckTarget)
+add_cppcheck_target(*.*pp)
+
+
+#-----------------------------------------------------------------------------
+#
+#  Decide which C++ version to use (Minimum/default: C++11).
+#
+#-----------------------------------------------------------------------------
+
+if(NOT MSVC)
+    if(NOT USE_CPP_VERSION)
+        set(USE_CPP_VERSION c++11)
+    endif()
+    message(STATUS "Use C++ version: ${USE_CPP_VERSION}")
+    # following only available from cmake 2.8.12:
+    #   add_compile_options(-std=${USE_CPP_VERSION})
+    # so using this instead:
+    add_definitions(-std=${USE_CPP_VERSION})
+endif()
+
+
+#-----------------------------------------------------------------------------
+#
+#  Compiler and Linker flags
+#
+#-----------------------------------------------------------------------------
+if(MSVC)
+    set(USUAL_COMPILE_OPTIONS "/Ox")
+else()
+    set(USUAL_COMPILE_OPTIONS "-O3 -g")
+endif()
+
+if(WIN32)
+    add_definitions(-DWIN32 -D_WIN32 -DMSWIN32 -DBGDWIN32
+                    -DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -D_WIN32_IE=0x0600)
+endif()
+
+set(CMAKE_CXX_FLAGS_DEV "${USUAL_COMPILE_OPTIONS}"
+    CACHE STRING "Flags used by the compiler during developer builds."
+    FORCE)
+
+set(CMAKE_EXE_LINKER_FLAGS_DEV ""
+    CACHE STRING "Flags used by the linker during developer builds."
+    FORCE)
+mark_as_advanced(
+    CMAKE_CXX_FLAGS_DEV
+    CMAKE_EXE_LINKER_FLAGS_DEV
+)
+
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${USUAL_COMPILE_OPTIONS}"
+    CACHE STRING "Flags used by the compiler during RELWITHDEBINFO builds."
+    FORCE)
+
+
+#-----------------------------------------------------------------------------
+#
+#  Build Type
+#
+#-----------------------------------------------------------------------------
+set(CMAKE_CONFIGURATION_TYPES "Debug Release RelWithDebInfo MinSizeRel Dev")
+
+# In 'Dev' mode: compile with very strict warnings and turn them into errors.
+if(CMAKE_BUILD_TYPE STREQUAL "Dev")
+    if(NOT MSVC)
+        add_definitions(-Werror)
+    endif()
+    add_definitions(${OSMIUM_WARNING_OPTIONS})
+endif()
+
+# Force RelWithDebInfo build type if none was given
+if(CMAKE_BUILD_TYPE)
+    set(build_type ${CMAKE_BUILD_TYPE})
+else()
+    set(build_type "RelWithDebInfo")
+endif()
+
+set(CMAKE_BUILD_TYPE ${build_type}
+    CACHE STRING
+    "Choose the type of build, options are: ${CMAKE_CONFIGURATION_TYPES}."
+    FORCE)
+
+
+#-----------------------------------------------------------------------------
diff --git a/export_to_wkt/.gitignore b/export_to_wkt/.gitignore
new file mode 100644
index 0000000..362f003
--- /dev/null
+++ b/export_to_wkt/.gitignore
@@ -0,0 +1 @@
+export_to_wkt
diff --git a/export_to_wkt/CMakeLists.txt b/export_to_wkt/CMakeLists.txt
new file mode 100644
index 0000000..3e08e79
--- /dev/null
+++ b/export_to_wkt/CMakeLists.txt
@@ -0,0 +1,24 @@
+#----------------------------------------------------------------------
+#
+#  Single example osmium-contrib CMakeLists.txt
+#
+#----------------------------------------------------------------------
+project(osmium-amenity-list)
+
+cmake_minimum_required(VERSION 2.8.5)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake")
+
+find_package(Boost REQUIRED)
+include_directories(${Boost_INCLUDE_DIRS})
+
+find_package(Osmium REQUIRED COMPONENTS io sparsehash)
+include_directories(${OSMIUM_INCLUDE_DIRS})
+
+include(common)
+
+#----------------------------------------------------------------------
+
+set(PROG export_to_wkt)
+file(GLOB SOURCES *.cpp *.hpp)
+add_executable(${PROG} ${SOURCES})
+target_link_libraries(${PROG} ${Boost_LIBRARIES} ${OSMIUM_LIBRARIES})
diff --git a/export_to_wkt/Makefile b/export_to_wkt/Makefile
new file mode 100644
index 0000000..8f43712
--- /dev/null
+++ b/export_to_wkt/Makefile
@@ -0,0 +1,12 @@
+
+all:
+	mkdir -p build && cd build && cmake .. && $(MAKE)
+
+clean:
+	if test -d build; then cd build && $(MAKE) clean; fi
+
+distclean:
+	rm -fr build
+
+.PHONY: clean distclean
+
diff --git a/export_to_wkt/README.md b/export_to_wkt/README.md
new file mode 100644
index 0000000..83658d6
--- /dev/null
+++ b/export_to_wkt/README.md
@@ -0,0 +1,45 @@
+
+# Export to WKT
+
+Write all node, way, and area geometries out in WKT format.
+
+
+## Prerequisites
+
+You'll need libosmium (http://osmcode.org/libosmium) and its dependencies
+installed first.
+
+
+## Building
+
+Osmium-contrib uses CMake for its builds. For Unix/Linux systems a simple
+Makefile wrapper is provided to make the build even easier.
+
+To build just type `make`. Results will be in the `build` subdirectory.
+
+Or you can go the long route explicitly calling CMake as follows:
+
+```
+mkdir build
+cd build
+cmake ..
+make
+```
+
+
+## Running
+
+Run the program with an OSM file as its only argument:
+
+`export_to_wkt berlin.osm.pbf`
+
+
+## License
+
+This program is released into the Public Domain.
+
+
+## Author
+
+Jochen Topf (http://jochentopf.com/)
+
diff --git a/export_to_wkt/export_to_wkt.cpp b/export_to_wkt/export_to_wkt.cpp
new file mode 100755
index 0000000..e8c71ee
--- /dev/null
+++ b/export_to_wkt/export_to_wkt.cpp
@@ -0,0 +1,77 @@
+
+// The code in this file is released into the Public Domain.
+
+#include <iostream>
+#include <string>
+
+#include <osmium/area/assembler.hpp>
+#include <osmium/area/multipolygon_collector.hpp>
+#include <osmium/geom/wkt.hpp>
+#include <osmium/handler.hpp>
+#include <osmium/io/any_input.hpp>
+#include <osmium/visitor.hpp>
+
+#include <osmium/index/map/sparse_mem_array.hpp>
+#include <osmium/handler/node_locations_for_ways.hpp>
+typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
+typedef osmium::handler::NodeLocationsForWays<index_type> location_handler_type;
+
+class ExportToWKTHandler : public osmium::handler::Handler {
+
+    osmium::geom::WKTFactory<> m_factory;
+
+public:
+
+    void node(const osmium::Node& node) {
+        std::cout << 'n' << node.id() << ' ' << m_factory.create_point(node) << "\n";
+    }
+
+    void way(const osmium::Way& way) {
+        try {
+            std::cout << 'w' << way.id() << ' ' << m_factory.create_linestring(way) << "\n";
+        } catch (osmium::geometry_error&) {
+            // ignore broken geometries (such as ways with only a single node)
+        }
+    }
+
+    void area(const osmium::Area& area) {
+        try {
+            std::cout << 'a' << area.id() << ' ' << m_factory.create_multipolygon(area) << "\n";
+        } catch (osmium::geometry_error&) {
+            // ignore broken geometries (such as illegal multipolygons)
+        }
+    }
+
+}; // class ExportToWKTHandler
+
+int main(int argc, char* argv[]) {
+    if (argc != 2) {
+        std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
+        exit(1);
+    }
+
+    std::string input_filename {argv[1]};
+
+    osmium::area::Assembler::config_type assembler_config;
+    osmium::area::MultipolygonCollector<osmium::area::Assembler> collector(assembler_config);
+
+    std::cerr << "Pass 1...\n";
+    osmium::io::Reader reader1(input_filename);
+    collector.read_relations(reader1);
+    std::cerr << "Pass 1 done\n";
+
+    index_type index;
+    location_handler_type location_handler(index);
+
+    std::cerr << "Pass 2...\n";
+    ExportToWKTHandler export_handler;
+    osmium::io::Reader reader2(input_filename);
+    osmium::apply(reader2, location_handler, export_handler, collector.handler([&export_handler](const osmium::memory::Buffer& buffer) {
+        osmium::apply(buffer, export_handler);
+    }));
+    std::cerr << "Pass 2 done\n";
+
+    google::protobuf::ShutdownProtobufLibrary();
+
+}
+
diff --git a/mapolution/.gitignore b/mapolution/.gitignore
new file mode 100644
index 0000000..95afeea
--- /dev/null
+++ b/mapolution/.gitignore
@@ -0,0 +1,3 @@
+mapolution
+*.o
+anim.gif
diff --git a/mapolution/CMakeLists.txt b/mapolution/CMakeLists.txt
new file mode 100644
index 0000000..2e45839
--- /dev/null
+++ b/mapolution/CMakeLists.txt
@@ -0,0 +1,31 @@
+#----------------------------------------------------------------------
+#
+#  Single example osmium-contrib CMakeLists.txt
+#
+#----------------------------------------------------------------------
+project(osmium-mapolution)
+
+cmake_minimum_required(VERSION 2.8.5)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake")
+
+find_package(Boost REQUIRED COMPONENTS program_options filesystem system)
+include_directories(${Boost_INCLUDE_DIRS})
+
+find_package(Osmium REQUIRED COMPONENTS io gdal proj sparsehash)
+include_directories(${OSMIUM_INCLUDE_DIRS})
+
+include(common)
+
+#----------------------------------------------------------------------
+
+if(HANDLER)
+    add_definitions(-DHANDLER=${HANDLER})
+    message(STATUS "Using handler: ${HANDLER}")
+endif()
+
+#----------------------------------------------------------------------
+
+set(PROG mapolution)
+file(GLOB SOURCES *.cpp *.hpp)
+add_executable(${PROG} ${SOURCES})
+target_link_libraries(${PROG} ${Boost_LIBRARIES} ${OSMIUM_LIBRARIES})
diff --git a/mapolution/Makefile b/mapolution/Makefile
new file mode 100644
index 0000000..8f43712
--- /dev/null
+++ b/mapolution/Makefile
@@ -0,0 +1,12 @@
+
+all:
+	mkdir -p build && cd build && cmake .. && $(MAKE)
+
+clean:
+	if test -d build; then cd build && $(MAKE) clean; fi
+
+distclean:
+	rm -fr build
+
+.PHONY: clean distclean
+
diff --git a/mapolution/README.md b/mapolution/README.md
new file mode 100644
index 0000000..a44918c
--- /dev/null
+++ b/mapolution/README.md
@@ -0,0 +1,70 @@
+
+# Mapolution
+
+Show evolution of OSM map.
+
+## Prerequisites
+
+You'll need:
+
+* libosmium (http://osmcode.org/libosmium) and its dependencies.
+* gdal (http://gdal.org/) library, more specifically the `gdal_rasterize`
+  command. (On Debian/Ubuntu install `libgdal-dev` and `gdal-bin` packages.)
+* `boost_filesystem` and `boost_program_options`
+  (http://boost.org/) version 1.48 or later.
+  (On Debian/Ubuntu install `libboost-filesystem-dev`,
+  and `libboost-program-options-dev` packages.)
+
+
+## Building
+
+Osmium-contrib uses CMake for its builds. For Unix/Linux systems a simple
+Makefile wrapper is provided to make the build even easier.
+
+To build just type `make`. Results will be in the `build` subdirectory.
+
+Or you can go the long route explicitly calling CMake as follows:
+
+    mkdir build
+    cd build
+    cmake ..
+    make
+
+You can switch to a different handler:
+
+    cmake -DHANDLER=RoadsHandler
+
+Available handlers are `BuildingsHandler`, `RestaurantsHandler`, and
+`RoadsHandler`. See the `handlers` directory. You can write you own handler
+easily.
+
+
+# Running
+
+First you need a full history dump extract of a city or so. The area
+can't be too large, because everything has to fit into memory. See
+http://osm.personalwerk.de/full-history-extracts/ for some downloads.
+
+Run
+
+    ./mapolution -S 30 OSMFILE
+
+This will create shapefiles in `out` directory with building data for
+every 30 days.
+
+Then run
+
+    ./rasterize.sh
+
+This will create an animated GIF called `anim.gif` with the result.
+
+
+# Customizing
+
+See `./mapolution --help` for more parameters.
+
+See the beginning of the `rasterize.sh` script for some parameters.
+
+See the `handlers` directory for how to create handlers and create
+your own. You have to add an include directive to `main.cpp`.
+
diff --git a/mapolution/cmdline_options.cpp b/mapolution/cmdline_options.cpp
new file mode 100644
index 0000000..ce64a62
--- /dev/null
+++ b/mapolution/cmdline_options.cpp
@@ -0,0 +1,105 @@
+
+#include "cmdline_options.hpp"
+
+#include <boost/program_options.hpp>
+
+osmium::Timestamp Options::parse_time(std::string t) {
+    try {
+        t.append("T00:00:00Z");
+        osmium::Timestamp ts(t.c_str());
+
+        if (ts < osmium::Timestamp("2005-01-01T00:00:00Z")) {
+            std::cerr << "Dates before 2005 don't make sense, because OSM didn't exist then.\n";
+            exit(return_code::fatal);
+        }
+
+        return ts;
+    } catch (std::invalid_argument&) {
+        std::cerr << "Can't understand the date, format should be YYYY-MM-DD.\n";
+        exit(return_code::fatal);
+    }
+}
+
+Options::Options(int argc, char* argv[]) {
+    namespace po = boost::program_options;
+
+    po::variables_map vm;
+
+    try {
+        po::options_description cmdline("Allowed options");
+        cmdline.add_options()
+            ("help,h", "Print this help message")
+            ("quiet,q", "Suppress verbose output messages")
+            ("output,o", po::value<std::string>(), "Output directory")
+            ("output-format,f", po::value<std::string>(), "OGR format of output files")
+            ("input-format,F", po::value<std::string>(), "Format of input file")
+            ("crs,c", po::value<int>(), "EPSG code of Coordinate Reference System")
+            ("start-time,s", po::value<std::string>(), "Start time (yyyy-mm-dd)")
+            ("end-time,e", po::value<std::string>(), "End time (yyyy-mm-dd)")
+            ("time-step,S", po::value<int>(), "Time step in days (default: 7 days)")
+        ;
+
+        po::options_description hidden("Hidden options");
+        hidden.add_options()
+            ("input-filename", po::value<std::string>(), "Input file")
+        ;
+
+        po::options_description desc("Usage: mapolution [OPTIONS] OSMFILE");
+        desc.add(cmdline);
+
+        po::options_description all;
+        all.add(cmdline).add(hidden);
+
+        po::positional_options_description positional;
+        positional.add("input-filename", 1);
+
+        po::store(po::command_line_parser(argc, argv).options(all).positional(positional).run(), vm);
+        po::notify(vm);
+
+        if (vm.count("help")) {
+            std::cout << desc << "\n";
+            exit(0);
+        }
+
+        if (vm.count("quiet")) {
+            vout.verbose(false);
+        }
+
+        if (vm.count("output")) {
+            output_directory = vm["output"].as<std::string>();
+        }
+
+        if (vm.count("input-filename")) {
+            input_filename = vm["input-filename"].as<std::string>();
+        }
+
+        if (vm.count("input-format")) {
+            input_format = vm["input-format"].as<std::string>();
+        }
+
+        if (vm.count("output-format")) {
+            output_format = vm["output-format"].as<std::string>();
+        }
+
+        if (vm.count("crs")) {
+            epsg = vm["crs"].as<int>();
+        }
+
+        if (vm.count("start-time")) {
+            start_time = parse_time(vm["start-time"].as<std::string>());
+        }
+
+        if (vm.count("end-time")) {
+            end_time = parse_time(vm["end-time"].as<std::string>());
+        }
+
+        if (vm.count("time-step")) {
+            time_step = vm["time-step"].as<int>();
+        }
+
+    } catch (boost::program_options::error& e) {
+        std::cerr << "Error parsing command line: " << e.what() << std::endl;
+        exit(return_code::fatal);
+    }
+}
+
diff --git a/mapolution/cmdline_options.hpp b/mapolution/cmdline_options.hpp
new file mode 100644
index 0000000..3482a21
--- /dev/null
+++ b/mapolution/cmdline_options.hpp
@@ -0,0 +1,35 @@
+#ifndef CMDLINE_OPTIONS_HPP
+#define CMDLINE_OPTIONS_HPP
+
+#include <string>
+
+#include <osmium/osm/timestamp.hpp>
+#include <osmium/util/verbose_output.hpp>
+
+enum return_code : int {
+    okay  = 0,
+    error = 1,
+    fatal = 2
+};
+
+struct Options {
+
+    osmium::util::VerboseOutput vout {true};
+
+    std::string input_filename {"-"};
+    std::string output_directory {"out"};
+    std::string input_format;
+    std::string output_format {"ESRI Shapefile"};
+    int epsg = 4326;
+
+    osmium::Timestamp start_time;
+    osmium::Timestamp end_time;
+    int time_step = 7; // default is 7 days == one week
+
+    Options(int argc, char* argv[]);
+
+    osmium::Timestamp parse_time(std::string);
+
+}; // struct Options
+
+#endif // CMDLINE_OPTIONS_HPP
diff --git a/mapolution/gdalcpp.hpp b/mapolution/gdalcpp.hpp
new file mode 100644
index 0000000..82dcd65
--- /dev/null
+++ b/mapolution/gdalcpp.hpp
@@ -0,0 +1,221 @@
+#ifndef GDALCPP_HPP
+#define GDALCPP_HPP
+
+#include <algorithm>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable : 4458)
+#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
+
+#include <gdal_priv.h>
+#include <gdal_version.h>
+#include <ogr_api.h>
+#include <ogrsf_frmts.h>
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#else
+# pragma GCC diagnostic pop
+#endif
+
+/**
+ * C++11 convenience wrapper classes for GDAL/OGR.
+ */
+namespace gdalcpp {
+
+#if GDAL_VERSION_MAJOR >= 2
+    typedef GDALDriver gdal_driver_type;
+    typedef GDALDataset gdal_dataset_type;
+#else
+    typedef OGRSFDriver gdal_driver_type;
+    typedef OGRDataSource gdal_dataset_type;
+#endif
+
+    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& name) :
+                init_library(),
+                m_driver(OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(name.c_str())) {
+                if (!m_driver) {
+                    throw std::runtime_error("unknown 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 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
+
+        detail::Options m_options;
+        std::unique_ptr<gdal_dataset_type, gdal_dataset_deleter> m_dataset;
+        OGRSpatialReference m_spatial_reference;
+
+    public:
+
+        Dataset(const std::string& driver, const std::string& name, const std::string& proj, const std::vector<std::string>& options = {}) :
+            m_options(options),
+#if GDAL_VERSION_MAJOR >= 2
+            m_dataset(detail::Driver(driver).get().Create(name.c_str(), 0, 0, 0, GDT_Unknown, m_options.get())) {
+#else
+            m_dataset(detail::Driver(driver).get().CreateDataSource(name.c_str(), m_options.get())) {
+#endif
+            if (!m_dataset) {
+                throw std::runtime_error("creating data source '" + name + "' failed");
+            }
+            m_spatial_reference.importFromProj4(proj.c_str());
+        }
+
+        gdal_dataset_type& get() const {
+            return *m_dataset;
+        }
+
+        OGRSpatialReference* spatial_reference() {
+            return &m_spatial_reference;
+        }
+
+    }; // class Dataset
+
+    class Layer {
+
+        OGRLayer* m_layer;
+
+    public:
+
+        Layer(Dataset& dataset, const std::string& name, OGRwkbGeometryType type) :
+            m_layer(dataset.get().CreateLayer(name.c_str(), dataset.spatial_reference(), type)) {
+            if (!m_layer) {
+                throw std::runtime_error("layer creation failed");
+            }
+        }
+
+        OGRLayer* get() const {
+            return m_layer;
+        }
+
+        Layer& add_field(const std::string& name, OGRFieldType type, int width, int precision=0) {
+            OGRFieldDefn field(name.c_str(), type);
+            field.SetWidth(width);
+            field.SetPrecision(precision);
+
+            if (m_layer->CreateField(&field) != OGRERR_NONE) {
+                throw std::runtime_error("field creation failed");
+            }
+
+            return *this;
+        }
+
+        Layer& StartTransaction() {
+            m_layer->StartTransaction();
+            return *this;
+        }
+
+        Layer& CommitTransaction() {
+            m_layer->CommitTransaction();
+            return *this;
+        }
+
+    }; // class Layer
+
+    class Feature {
+
+        OGRLayer* m_layer;
+        OGRFeature m_feature;
+
+    public:
+
+        Feature(Layer& layer, std::unique_ptr<OGRGeometry>&& geometry) :
+            m_layer(layer.get()),
+            m_feature(m_layer->GetLayerDefn()) {
+            m_feature.SetGeometry(geometry.get());
+        }
+
+        void add_to_layer() {
+            if (m_layer->CreateFeature(&m_feature) != OGRERR_NONE) {
+                std::runtime_error("feature creation failed");
+            }
+        }
+
+        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
diff --git a/mapolution/geom_handler.hpp b/mapolution/geom_handler.hpp
new file mode 100644
index 0000000..ec3b994
--- /dev/null
+++ b/mapolution/geom_handler.hpp
@@ -0,0 +1,63 @@
+#ifndef GEOM_HANDLER_HPP
+#define GEOM_HANDLER_HPP
+
+#include "gdalcpp.hpp"
+
+#include <osmium/geom/ogr.hpp>
+#include <osmium/geom/projection.hpp>
+
+class GeomHandler : public osmium::handler::Handler {
+
+public:
+
+    typedef osmium::geom::OGRFactory<osmium::geom::Projection> factory_type;
+
+private:
+
+    factory_type& m_factory;
+    OGREnvelope m_envelope;
+
+    gdalcpp::Dataset& m_dataset;
+
+public:
+
+    GeomHandler(factory_type& factory, gdalcpp::Dataset& dataset) :
+        m_factory(factory),
+        m_dataset(dataset) {
+    }
+
+    gdalcpp::Dataset& dataset() const {
+        return m_dataset;
+    }
+
+    OGREnvelope envelope() const {
+        return m_envelope;
+    }
+
+    std::unique_ptr<OGRPoint> create_point(const osmium::Node& node) {
+        std::unique_ptr<OGRPoint> geom = m_factory.create_point(node);
+        OGREnvelope env;
+        geom->getEnvelope(&env);
+        m_envelope.Merge(env);
+        return geom;
+    }
+
+    std::unique_ptr<OGRLineString> create_linestring(const osmium::Way& way) {
+        std::unique_ptr<OGRLineString> geom = m_factory.create_linestring(way);
+        OGREnvelope env;
+        geom->getEnvelope(&env);
+        m_envelope.Merge(env);
+        return geom;
+    }
+
+    std::unique_ptr<OGRMultiPolygon> create_multipolygon(const osmium::Area& area) {
+        std::unique_ptr<OGRMultiPolygon> geom = m_factory.create_multipolygon(area);
+        OGREnvelope env;
+        geom->getEnvelope(&env);
+        m_envelope.Merge(env);
+        return geom;
+    }
+
+}; // class GeomHandler
+
+#endif // GEOM_HANDLER_HPP
diff --git a/mapolution/handlers/buildings.hpp b/mapolution/handlers/buildings.hpp
new file mode 100644
index 0000000..505abb2
--- /dev/null
+++ b/mapolution/handlers/buildings.hpp
@@ -0,0 +1,43 @@
+#ifndef HANDLERS_BUILDINGS_HPP
+#define HANDLERS_BUILDINGS_HPP
+
+class BuildingsHandler : public GeomHandler {
+
+    gdalcpp::Layer m_layer;
+
+public:
+
+    BuildingsHandler(factory_type& factory, gdalcpp::Dataset& ds, const std::string& date) :
+        GeomHandler(factory, ds),
+        m_layer(dataset(), "buildings_" + date, wkbMultiPolygon) {
+        m_layer.add_field("id", OFTInteger, 10);
+        m_layer.StartTransaction();
+    }
+
+    ~BuildingsHandler() {
+        m_layer.CommitTransaction();
+        if (m_layer.get()->GetFeatureCount() == 0) {
+            std::cerr << "WARNING: No features in layer '" << m_layer.get()->GetName() << "'.\n";
+        }
+    }
+
+    void area(const osmium::Area& area) {
+        try {
+            const char* building = area.tags()["building"];
+            if (building) {
+                gdalcpp::Feature f(m_layer, create_multipolygon(area));
+                f.set_field("id", static_cast<int>(area.id()));
+                f.add_to_layer();
+            }
+        } catch (osmium::not_found&) {
+            // ignore missing node locations
+        } catch (osmium::invalid_location&) {
+            // ignore missing node locations
+        } catch (osmium::geometry_error&) {
+            // ignore broken geometries (such as illegal multipolygons)
+        }
+    }
+
+}; // class BuildingsHandler
+
+#endif // HANDLERS_BUILDINGS_HPP
diff --git a/mapolution/handlers/restaurants.hpp b/mapolution/handlers/restaurants.hpp
new file mode 100644
index 0000000..a98ba70
--- /dev/null
+++ b/mapolution/handlers/restaurants.hpp
@@ -0,0 +1,59 @@
+#ifndef HANDLERS_RESTAURANTS_HPP
+#define HANDLERS_RESTAURANTS_HPP
+
+class RestaurantsHandler : public GeomHandler {
+
+    gdalcpp::Layer m_layer;
+
+public:
+
+    RestaurantsHandler(factory_type& factory, gdalcpp::Dataset& ds, const std::string& date) :
+        GeomHandler(factory, ds),
+        m_layer(dataset(), "restaurants_" + date, wkbPoint) {
+        m_layer.add_field("id", OFTReal, 10);
+        m_layer.StartTransaction();
+    }
+
+    ~RestaurantsHandler() {
+        m_layer.CommitTransaction();
+    }
+
+    void node(const osmium::Node& node) {
+        try {
+            const char* amenity = node.tags()["amenity"];
+            if (amenity && !strcmp(amenity, "restaurant")) {
+                gdalcpp::Feature f(m_layer, create_point(node));
+                f.set_field("id", static_cast<double>(node.id()));
+                f.add_to_layer();
+            }
+        } catch (osmium::not_found&) {
+            // ignore missing node locations
+        } catch (osmium::invalid_location&) {
+            // ignore missing node locations
+        } catch (osmium::geometry_error&) {
+            // ignore broken geometries (such as illegal multipolygons)
+        }
+    }
+
+#if 0
+    void area(const osmium::Area& area) {
+        try {
+            const char* amenity = area.tags()["amenity"];
+            if (amenity && !strcmp(amenity, "restaurant")) {
+                gdalcpp::Feature f(m_layer, create_point(area.)); // get one node XXX
+                f.set_field("id", static_cast<int>(area.id()));
+                f.add_to_layer();
+            }
+        } catch (osmium::not_found&) {
+            // ignore missing node locations
+        } catch (osmium::invalid_location&) {
+            // ignore missing node locations
+        } catch (osmium::geometry_error&) {
+            // ignore broken geometries (such as illegal multipolygons)
+        }
+    }
+#endif
+
+}; // class RestaurantsHandler
+
+#endif // HANDLERS_RESTAURANTS_HPP
diff --git a/mapolution/handlers/roads.hpp b/mapolution/handlers/roads.hpp
new file mode 100644
index 0000000..70cad85
--- /dev/null
+++ b/mapolution/handlers/roads.hpp
@@ -0,0 +1,42 @@
+#ifndef HANDLERS_ROADS_HPP
+#define HANDLERS_ROADS_HPP
+
+class RoadsHandler : public GeomHandler {
+
+    gdalcpp::Layer m_layer;
+
+public:
+
+    RoadsHandler(factory_type& factory, gdalcpp::Dataset& ds, const std::string& date) :
+        GeomHandler(factory, ds),
+        m_layer(dataset(), "roads_" + date, wkbLineString) {
+        m_layer.add_field("id", OFTInteger, 10);
+        m_layer.add_field("type", OFTString, 30);
+        m_layer.StartTransaction();
+    }
+
+    ~RoadsHandler() {
+        m_layer.CommitTransaction();
+    }
+
+    void way(const osmium::Way& way) {
+        try {
+            const char* highway = way.tags()["highway"];
+            if (highway) {
+                gdalcpp::Feature f(m_layer, create_linestring(way));
+                f.set_field("id", static_cast<int>(way.id()));
+                f.set_field("type", highway);
+                f.add_to_layer();
+            }
+        } catch (osmium::not_found&) {
+            // ignore missing node locations
+        } catch (osmium::invalid_location&) {
+            // ignore missing node locations
+        } catch (osmium::geometry_error&) {
+            // ignore broken geometries (such as ways with only a single node)
+        }
+    }
+
+}; // class RoadsHandler
+
+#endif // HANDLERS_ROADS_HPP
diff --git a/mapolution/main.cpp b/mapolution/main.cpp
new file mode 100644
index 0000000..24ac894
--- /dev/null
+++ b/mapolution/main.cpp
@@ -0,0 +1,253 @@
+
+#include <numeric>
+#include <fstream>
+
+#include <boost/filesystem.hpp>
+
+#include <osmium/area/assembler.hpp>
+#include <osmium/area/multipolygon_collector.hpp>
+#include <osmium/diff_iterator.hpp>
+#include <osmium/handler.hpp>
+#include <osmium/io/any_input.hpp>
+#include <osmium/visitor.hpp>
+
+#include <osmium/index/map/sparse_mem_array.hpp>
+#include <osmium/handler/node_locations_for_ways.hpp>
+typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
+typedef osmium::handler::NodeLocationsForWays<index_type> location_handler_type;
+
+#include "cmdline_options.hpp"
+#include "geom_handler.hpp"
+
+#include "handlers/buildings.hpp"
+#include "handlers/restaurants.hpp"
+#include "handlers/roads.hpp"
+
+constexpr size_t initial_buffer_size = 10 * 1024 * 1024;
+
+OGREnvelope extract(
+        Options& options,
+        osmium::geom::OGRFactory<osmium::geom::Projection>& factory,
+        osmium::memory::Buffer::t_iterator<osmium::OSMObject> begin,
+        osmium::memory::Buffer::t_iterator<osmium::OSMObject> relations,
+        osmium::memory::Buffer::t_iterator<osmium::OSMObject> end,
+        osmium::Timestamp point_in_time) {
+
+    options.vout << "Working on " << point_in_time << "...\n";
+    options.vout << "  Filtering data...\n";
+
+    // nodes and ways
+    typedef osmium::DiffIterator<osmium::memory::Buffer::t_iterator<osmium::OSMObject>> diff_iterator;
+    osmium::memory::Buffer fbuffer(initial_buffer_size, osmium::memory::Buffer::auto_grow::yes);
+    {
+        auto dbegin = diff_iterator(begin, relations);
+        auto dend   = diff_iterator(relations, relations);
+
+        std::for_each(dbegin, dend, [point_in_time, &fbuffer](const osmium::DiffObject& d) {
+            if (((d.end_time() == 0 || d.end_time() > point_in_time) &&
+                    d.start_time() <= point_in_time) &&
+                d.curr().visible()) {
+                fbuffer.add_item(d.curr());
+                fbuffer.commit();
+            }
+        });
+    }
+    options.vout << "  Done. Filtered data needs "
+                 << (fbuffer.committed() / (1024 * 1024))
+                 << " MBytes.\n";
+
+    // relations
+    osmium::memory::Buffer rbuffer(initial_buffer_size, osmium::memory::Buffer::auto_grow::yes);
+    {
+        auto dbegin = diff_iterator(relations, end);
+        auto dend   = diff_iterator(end, end);
+
+        std::for_each(dbegin, dend, [point_in_time, &rbuffer](const osmium::DiffObject& d) {
+            if (((d.end_time() == 0 || d.end_time() > point_in_time) &&
+                    d.start_time() <= point_in_time) &&
+                d.curr().visible()) {
+                rbuffer.add_item(d.curr());
+                rbuffer.commit();
+            }
+        });
+    }
+
+    osmium::area::Assembler::config_type assembler_config;
+    osmium::area::MultipolygonCollector<osmium::area::Assembler> collector(assembler_config);
+
+    options.vout << "  Reading relations...\n";
+    collector.read_relations(rbuffer.cbegin(), rbuffer.cend());
+
+    index_type index_pos;
+    location_handler_type location_handler(index_pos);
+    location_handler.ignore_errors();
+
+    options.vout << "  Creating geometries...\n";
+    std::string date = point_in_time.to_iso().substr(0, 10);
+
+    std::vector<std::string> datasource_options;
+    std::string datasource_name = options.output_directory + "/" + date;
+    if (options.output_format == "GeoJSON") {
+        datasource_name += ".json";
+    } else if (options.output_format == "SQLite") {
+        datasource_name += ".db";
+        datasource_options.push_back("SPATIALITE=TRUE");
+        CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
+        CPLSetConfigOption("OGR_SQLITE_CACHE", "512");
+    }
+
+    gdalcpp::Dataset dataset(options.output_format, datasource_name, factory.proj_string(), datasource_options);
+
+#ifdef HANDLER
+    HANDLER geom_handler(factory, dataset, date);
+#else
+    BuildingsHandler geom_handler(factory, dataset, date);
+#endif
+    osmium::apply(fbuffer.begin(),
+                  fbuffer.end(),
+                  location_handler,
+                  geom_handler,
+                  collector.handler([&geom_handler](const osmium::memory::Buffer& buffer) {
+        osmium::apply(buffer, geom_handler);
+    }));
+
+    return geom_handler.envelope();
+}
+
+typedef std::pair<osmium::Timestamp, osmium::Timestamp> tspair;
+template <class TIter>
+tspair min_max_timestamp(TIter begin, TIter end) {
+    tspair init = std::make_pair(osmium::end_of_time(), osmium::start_of_time());
+    return std::accumulate(begin, end, init, [](tspair start_end, const osmium::OSMObject& obj) -> tspair {
+        if (obj.timestamp() < start_end.first) {
+            start_end.first = obj.timestamp();
+        }
+        if (obj.timestamp() > start_end.second) {
+            start_end.second = obj.timestamp();
+        }
+        return start_end;
+    });
+}
+
+void check_and_create_directory(const std::string& directory) {
+    boost::filesystem::path dir(directory);
+
+    try {
+        boost::filesystem::create_directories(dir);
+    } catch (boost::filesystem::filesystem_error& e) {
+        std::cerr << "Error creating output directory '"
+                  << directory
+                  << "': "
+                  << e.what()
+                  << ".\n";
+        exit(return_code::fatal);
+    }
+
+    int num_entries = std::distance(boost::filesystem::directory_iterator(dir),
+                                    boost::filesystem::directory_iterator());
+
+    if (num_entries != 0) {
+        std::cerr << "Output directory '" << directory << "' is not empty.\n";
+        exit(return_code::fatal);
+    }
+}
+
+int main(int argc, char* argv[]) {
+    Options options(argc, argv);
+
+    options.vout << "Options from command line or defaults:\n";
+    options.vout << "  Input file:                  " << options.input_filename << "\n";
+    if (!options.input_format.empty()) {
+        options.vout << "  Input format:                " << options.input_format << "\n";
+    }
+    options.vout << "  Coordinate Reference System: " << options.epsg << "\n";
+    options.vout << "  Output directory:            " << options.output_directory << "\n";
+    options.vout << "  Output OGR format:           " << options.output_format << "\n";
+    if (options.start_time) {
+        options.vout << "  Start time:                  " << options.start_time << "\n";
+    }
+    if (options.end_time) {
+        options.vout << "  End time:                    " << options.end_time << "\n";
+    }
+    options.vout << "  Time steps:                  " << options.time_step << " day(s)\n";
+
+    if (options.start_time && options.end_time && options.start_time > options.end_time) {
+        options.vout << "Your end time is before the start time. Switching them around.\n";
+        std::swap(options.start_time, options.end_time);
+    }
+
+    check_and_create_directory(options.output_directory);
+
+    options.vout << "Reading input file into memory...\n";
+    osmium::io::File file(options.input_filename, options.input_format);
+    osmium::memory::Buffer ibuffer = osmium::io::read_file(file, osmium::osm_entity_bits::object);
+    options.vout << "Done. Input data needs " << (ibuffer.committed() / (1024 * 1024)) << " MBytes.\n";
+
+    auto first_relation = std::find_if(ibuffer.begin<osmium::OSMObject>(),
+                                       ibuffer.end<osmium::OSMObject>(),
+                                       [](const osmium::OSMObject& obj){
+        return obj.type() == osmium::item_type::relation;
+    });
+
+    const int seconds_per_day = 24 * 60 * 60;
+
+    osmium::Timestamp start_time = options.start_time;
+    osmium::Timestamp end_time = options.end_time;
+    if (!start_time || !end_time) {
+        tspair min_max = min_max_timestamp(ibuffer.cbegin<osmium::OSMObject>(),
+                                           ibuffer.cend<osmium::OSMObject>());
+
+        if (!start_time) {
+            options.vout << "No start time on command line, got it from file contents\n";
+            start_time = min_max.first / seconds_per_day * seconds_per_day;
+        }
+        if (!end_time) {
+            options.vout << "No end time on command line, got it from file contents\n";
+            end_time = min_max.second / seconds_per_day * seconds_per_day;
+        }
+    }
+
+    options.vout << "Start time: " << start_time << "\n";
+    options.vout << "End time  : " << end_time << "\n";
+
+    osmium::geom::OGRFactory<osmium::geom::Projection> factory(osmium::geom::Projection(options.epsg));
+
+    OGREnvelope envelope_all;
+    auto step = options.time_step * seconds_per_day;
+    for (osmium::Timestamp t = start_time; t <= end_time; t += step) {
+        OGREnvelope env = extract(
+            options,
+            factory,
+            ibuffer.begin<osmium::OSMObject>(),
+            first_relation,
+            ibuffer.end<osmium::OSMObject>(),
+            t
+        );
+        envelope_all.Merge(env);
+    }
+
+    std::ofstream env_out(options.output_directory + "/bbox", std::ofstream::out);
+    env_out << std::fixed
+            << "XMIN=" << envelope_all.MinX << "\n"
+            << "YMIN=" << envelope_all.MinY << "\n"
+            << "XMAX=" << envelope_all.MaxX << "\n"
+            << "YMAX=" << envelope_all.MaxY << "\n";
+
+    options.vout << "Bounding box calculated from output data: ("
+                 << std::fixed
+                 << envelope_all.MinX
+                 << ','
+                 << envelope_all.MinY
+                 << ") ("
+                 << envelope_all.MaxX
+                 << ','
+                 << envelope_all.MaxY
+                 << ")\n";
+
+    options.vout << "Done.\n";
+
+    google::protobuf::ShutdownProtobufLibrary();
+
+    return return_code::okay;
+}
+
diff --git a/mapolution/rasterize.sh b/mapolution/rasterize.sh
new file mode 100755
index 0000000..55e1a0e
--- /dev/null
+++ b/mapolution/rasterize.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+#  rasterize.sh
+#
+
+set -e
+
+RED=255
+GREEN=255
+BLUE=255
+
+DELAY=10
+
+WIDTH=1024
+
+# ------------------------
+
+DIR=out
+
+. $DIR/bbox
+
+geo_width=`echo "$XMAX - $XMIN" | bc -q | tail -1`
+geo_height=`echo "$YMAX - $YMIN" | bc -q | tail -1`
+
+ratio=`echo "$WIDTH / $geo_width" | bc -q | tail -1`
+HEIGHT=`echo "$geo_height * $ratio" | bc -q | tail -1 | cut -d. -f1`
+
+echo "Rasterizing vector data..."
+for i in out/????-??-??; do
+    date=`basename $i`
+    echo "  $date..."
+    gdal_rasterize -q -ot Byte -te $XMIN $YMIN $XMAX $YMAX -burn $RED -burn $GREEN -burn $BLUE -ts $WIDTH $HEIGHT $DIR/$date/*.shp $DIR/$date.tif
+    convert -quiet $DIR/$date.tif $DIR/$date.gif
+done
+
+echo "Creating GIF animation..."
+gifsicle --delay=$DELAY --optimize=3 --loop $DIR/*.gif > anim.gif
+
+echo "Done."
+
diff --git a/node_density/.gitignore b/node_density/.gitignore
new file mode 100644
index 0000000..7597305
--- /dev/null
+++ b/node_density/.gitignore
@@ -0,0 +1,3 @@
+node_density
+*.o
+*.tif
diff --git a/node_density/CMakeLists.txt b/node_density/CMakeLists.txt
new file mode 100644
index 0000000..d40f275
--- /dev/null
+++ b/node_density/CMakeLists.txt
@@ -0,0 +1,24 @@
+#----------------------------------------------------------------------
+#
+#  Single example osmium-contrib CMakeLists.txt
+#
+#----------------------------------------------------------------------
+project(osmium-node-density)
+
+cmake_minimum_required(VERSION 2.8.5)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake")
+
+find_package(Boost REQUIRED COMPONENTS program_options)
+include_directories(${Boost_INCLUDE_DIRS})
+
+find_package(Osmium REQUIRED COMPONENTS io gdal proj sparsehash)
+include_directories(${OSMIUM_INCLUDE_DIRS})
+
+include(common)
+
+#----------------------------------------------------------------------
+
+set(PROG node_density)
+file(GLOB SOURCES *.cpp *.hpp)
+add_executable(${PROG} ${SOURCES})
+target_link_libraries(${PROG} ${Boost_LIBRARIES} ${OSMIUM_LIBRARIES})
diff --git a/node_density/Makefile b/node_density/Makefile
new file mode 100644
index 0000000..8f43712
--- /dev/null
+++ b/node_density/Makefile
@@ -0,0 +1,12 @@
+
+all:
+	mkdir -p build && cd build && cmake .. && $(MAKE)
+
+clean:
+	if test -d build; then cd build && $(MAKE) clean; fi
+
+distclean:
+	rm -fr build
+
+.PHONY: clean distclean
+
diff --git a/node_density/README.md b/node_density/README.md
new file mode 100644
index 0000000..86a632d
--- /dev/null
+++ b/node_density/README.md
@@ -0,0 +1,109 @@
+
+# Node Density
+
+Visualize the node density in a given OSM file.
+
+
+## Prerequisites
+
+You'll need libosmium (http://osmcode.org/libosmium) and its dependencies
+installed first.
+
+You'll need the following libraries:
+
+GDAL
+    http://www.gdal.org/
+    Debian/Ubuntu: libgdal-dev, gdal-bin
+
+Proj
+    http://trac.osgeo.org/proj/
+    Debian/Ubuntu: libproj-dev
+
+
+## Building
+
+Osmium-contrib uses CMake for its builds. For Unix/Linux systems a simple
+Makefile wrapper is provided to make the build even easier.
+
+To build just type `make`. Results will be in the `build` subdirectory.
+
+Or you can go the long route explicitly calling CMake as follows:
+
+```
+mkdir build
+cd build
+cmake ..
+make
+```
+
+
+## Running
+
+Run the program with an OSM dump as its only argument:
+
+`node_density planet.osm.pbf`
+
+This will use some sensible default settings that are displayed after the
+program start. Depending on the settings this will run for several minutes.
+
+For available options see
+
+`node_density --help`
+
+
+## Viewing results
+
+The output of this program is a GeoTIFF file with 32bit integer values for each
+pixel. Your usual image viewers might not be able to display it. There are
+various ways to view it. The following descriptions expect the output to have
+the default name `out.tif`.
+
+### With QGIS
+
+Run [qgis](http://qgis.org/) and open the output file with it, either through
+the "Layer -> Add Raster Layer.." menu or by dragging the file onto the QGIS
+window. Open the "Layer Properties" dialogue, choose the "Style" tab and change
+the "Min" and "Max" values to "0" and "1000", respectively. You should see the
+result. Play around with the settings.
+
+If you have QGIS 2.4 or newer you can drag the `example.qlr` file onto your
+QGIS window. The `out.tif` file should be opened with some sample settings.
+(Currently this only works if qgis was started from the same directory the
+`example.qlr` and `out.tif` files are in.)
+
+To improve rendering speed in QGIS for large files add overview images by
+calling `node_density` with `--build-overviews`.
+
+
+### With GDAL
+
+There are several programs in the GDAL suite that can help with converting
+the GeoTIFF file in various ways.
+
+Convert into b/w PNG:
+
+```
+gdal_translate -ot Byte -of PNG -scale 0 200 out.tif out-bw.png
+```
+
+Try out different `-scale` settings. See the `gdal_translate` man page for
+details.
+
+To convert into a color PNG:
+
+```
+gdaldem color-relief out.tif colors.txt -of PNG out-color.png
+```
+
+An example `colors.txt` is part of the `node_density` distribution.
+
+
+## License
+
+This program is released into the Public Domain.
+
+
+## Author
+
+Jochen Topf (http://jochentopf.com/)
+
diff --git a/node_density/cmdline_options.cpp b/node_density/cmdline_options.cpp
new file mode 100644
index 0000000..f164b22
--- /dev/null
+++ b/node_density/cmdline_options.cpp
@@ -0,0 +1,125 @@
+
+#include "cmdline_options.hpp"
+
+#include <boost/program_options.hpp>
+
+Options::Options(int argc, char* argv[]) {
+    namespace po = boost::program_options;
+
+    po::variables_map vm;
+
+    try {
+        po::options_description cmdline("Options");
+        cmdline.add_options()
+            ("help,h", "Print this help message")
+            ("quiet,q", "Suppress verbose output messages")
+            ("format,f", po::value<std::string>(), "Format of input file (default: autodetect)")
+            ("output,o", po::value<std::string>(), "Name of output image")
+            ("epsg,e", po::value<int>(), "EPSG code of spatial reference system (default: 4326)")
+            ("srs,s", po::value<std::string>(), "Spatial reference system in proj format")
+            ("width,W", po::value<size_t>(), "Pixel width of output image")
+            ("height,H", po::value<size_t>(), "Pixel height of output image")
+            ("left,x", po::value<double>(), "Left edge of bounding box (default: -180)")
+            ("right,X", po::value<double>(), "Right edge of bounding box (default: 180)")
+            ("bottom,y", po::value<double>(), "Bottom edge of bounding box (default: -90)")
+            ("top,Y", po::value<double>(), "Top edge of bounding box (default: 90)")
+            ("compression", po::value<std::string>(), "Compression format (NONE, DEFLATE, or LZW (default: LZW))")
+            ("build-overviews", "Build overview images")
+        ;
+
+        po::options_description hidden("Hidden options");
+        hidden.add_options()
+            ("input-filename", po::value<std::string>(), "Input file")
+        ;
+
+        po::options_description desc("Usage: node_density [OPTIONS] OSMFILE\nCreate GeoTIFF with node density in OSM data");
+        desc.add(cmdline);
+
+        po::options_description all;
+        all.add(cmdline).add(hidden);
+
+        po::positional_options_description positional;
+        positional.add("input-filename", 1);
+
+        po::store(po::command_line_parser(argc, argv).options(all).positional(positional).run(), vm);
+        po::notify(vm);
+
+        if (vm.count("help")) {
+            std::cout << desc << "\n";
+            exit(0);
+        }
+
+        if (vm.count("quiet")) {
+            vout.verbose(false);
+        }
+
+        if (vm.count("input-filename")) {
+            input_filename = vm["input-filename"].as<std::string>();
+        }
+
+        if (vm.count("format")) {
+            input_format = vm["format"].as<std::string>();
+        }
+
+        if (vm.count("output")) {
+            output_filename = vm["output"].as<std::string>();
+        }
+
+        if (vm.count("srs") && vm.count("epsg")) {
+            std::cerr << "Use at most one of the options --epsg,-e and --srs,-s\n";
+            exit(return_code::fatal);
+        }
+
+        if (vm.count("srs")) {
+            srs = vm["srs"].as<std::string>();
+            epsg = -1;
+        }
+
+        if (vm.count("epsg")) {
+            epsg = vm["epsg"].as<int>();
+            srs = "+init=epsg:" + std::to_string(epsg);
+        }
+
+        if (vm.count("width")) {
+            width = vm["width"].as<size_t>();
+        }
+
+        if (vm.count("height")) {
+            height = vm["height"].as<size_t>();
+        }
+
+        if (vm.count("top")) {
+            box.top_right().set_lat(vm["top"].as<double>());
+        }
+
+        if (vm.count("right")) {
+            box.top_right().set_lon(vm["right"].as<double>());
+        }
+
+        if (vm.count("bottom")) {
+            box.bottom_left().set_lat(vm["bottom"].as<double>());
+        }
+
+        if (vm.count("left")) {
+            box.bottom_left().set_lon(vm["left"].as<double>());
+        }
+
+        if (vm.count("build-overviews")) {
+            build_overview = true;
+        }
+
+        if (vm.count("compression")) {
+            std::string c = vm["compression"].as<std::string>();
+            if (c == "NONE" || c == "LZW" || c == "DEFLATE") {
+                compression_format = c;
+            } else {
+                std::cerr << "Unknown compression format '" << c << "'\n";
+                exit(return_code::fatal);
+            }
+        }
+    } catch (boost::program_options::error& e) {
+        std::cerr << "Error parsing command line: " << e.what() << std::endl;
+        exit(return_code::fatal);
+    }
+}
+
diff --git a/node_density/cmdline_options.hpp b/node_density/cmdline_options.hpp
new file mode 100644
index 0000000..6811ce4
--- /dev/null
+++ b/node_density/cmdline_options.hpp
@@ -0,0 +1,35 @@
+#ifndef CMDLINE_OPTIONS_HPP
+#define CMDLINE_OPTIONS_HPP
+
+#include <string>
+
+#include <osmium/osm/box.hpp>
+#include <osmium/osm/timestamp.hpp>
+#include <osmium/util/verbose_output.hpp>
+
+enum return_code : int {
+    okay  = 0,
+    error = 1,
+    fatal = 2
+};
+
+struct Options {
+
+    osmium::util::VerboseOutput vout {true};
+
+    std::string input_filename {"-"};
+    std::string output_filename {"out.tif"};
+    std::string input_format;
+    std::string compression_format {"LZW"};
+    bool build_overview = false;
+    std::string srs {"+init=epsg:4326"};
+    int epsg = 4326;
+    size_t width = 1024;
+    size_t height = 512;
+    osmium::Box box {-180, -90, 180, 90};
+
+    Options(int argc, char* argv[]);
+
+}; // struct Options
+
+#endif // CMDLINE_OPTIONS_HPP
diff --git a/node_density/colors.txt b/node_density/colors.txt
new file mode 100644
index 0000000..711a853
--- /dev/null
+++ b/node_density/colors.txt
@@ -0,0 +1,5 @@
+0 0 0 0
+1 68 0 0
+3000 255 0 0
+8000 255 255 0
+10000 255 255 255
diff --git a/node_density/example.qlr b/node_density/example.qlr
new file mode 100644
index 0000000..c2a6477
--- /dev/null
+++ b/node_density/example.qlr
@@ -0,0 +1,49 @@
+<!DOCTYPE qgis-layer-definition>
+<maplayers>
+  <maplayer minimumScale="-4.65661e-10" maximumScale="1e+08" type="raster" hasScaleBasedVisibilityFlag="0">
+    <datasource>out.tif</datasource>
+    <title></title>
+    <abstract></abstract>
+    <keywordList>
+      <value></value>
+    </keywordList>
+    <layername>OSM node density</layername>
+    <srs>
+      <spatialrefsys>
+        <proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
+        <srsid>3452</srsid>
+        <srid>4326</srid>
+        <authid>EPSG:4326</authid>
+        <description>WGS 84</description>
+        <projectionacronym>longlat</projectionacronym>
+        <ellipsoidacronym>WGS84</ellipsoidacronym>
+        <geographicflag>true</geographicflag>
+      </spatialrefsys>
+    </srs>
+    <customproperties>
+      <property key="identify/format" value="Value"/>
+    </customproperties>
+    <provider>gdal</provider>
+    <noData>
+      <noDataList bandNo="1" useSrcNoData="0"/>
+    </noData>
+    <pipe>
+      <rasterrenderer opacity="1" alphaBand="0" classificationMax="120000" classificationMinMaxOrigin="User" band="1" classificationMin="0" type="singlebandpseudocolor">
+        <rasterTransparency/>
+        <rastershader>
+          <colorrampshader colorRampType="INTERPOLATED" clip="0">
+            <item alpha="255" value="0" label="0" color="#000000"/>
+            <item alpha="255" value="1" label="1" color="#440000"/>
+            <item alpha="255" value="3000" label="3000" color="#ff0000"/>
+            <item alpha="255" value="12000" label="12000" color="#ffff00"/>
+            <item alpha="255" value="120000" label="120000" color="#ffffff"/>
+          </colorrampshader>
+        </rastershader>
+      </rasterrenderer>
+      <brightnesscontrast brightness="0" contrast="0"/>
+      <huesaturation colorizeGreen="128" colorizeOn="0" colorizeRed="255" colorizeBlue="128" grayscaleMode="0" saturation="0" colorizeStrength="100"/>
+      <rasterresampler maxOversampling="0" zoomedOutResampler="bilinear"/>
+    </pipe>
+    <blendMode>0</blendMode>
+  </maplayer>
+</maplayers>
diff --git a/node_density/main.cpp b/node_density/main.cpp
new file mode 100644
index 0000000..0dac5ff
--- /dev/null
+++ b/node_density/main.cpp
@@ -0,0 +1,197 @@
+
+// The code in this file is released into the Public Domain.
+
+#include <algorithm>
+#include <cassert>
+#include <cmath>
+#include <cstdio>
+#include <iostream>
+#include <limits>
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#include <cpl_conv.h>
+#include <cpl_string.h>
+#include <gdal_priv.h>
+#include <ogr_spatialref.h>
+#pragma GCC diagnostic pop
+
+#include <osmium/io/any_input.hpp>
+#include <osmium/handler.hpp>
+#include <osmium/visitor.hpp>
+#include <osmium/geom/mercator_projection.hpp>
+#include <osmium/geom/projection.hpp>
+
+#include "cmdline_options.hpp"
+
+typedef uint32_t node_count_type;
+
+class NodeDensityHandler : public osmium::handler::Handler {
+
+    Options& m_options;
+
+    osmium::geom::Projection m_projection;
+
+    const int m_width;
+    const int m_height;
+
+    const osmium::geom::Coordinates m_bottom_left;
+    const osmium::geom::Coordinates m_top_right;
+
+    const double m_factor_x;
+    const double m_factor_y;
+
+    std::unique_ptr<node_count_type[]> m_node_count;
+
+    template <typename T>
+    static T in_range(T min, T value, T max) {
+        return std::min(std::max(value, min), max);
+    }
+
+    void record_location(const osmium::Location& location) {
+        if (m_options.box.contains(location)) {
+            osmium::geom::Coordinates c = m_projection(location);
+            const int x = in_range(0, static_cast<int>((c.x - m_bottom_left.x) * m_factor_x), m_width - 1);
+            const int y = in_range(0, static_cast<int>((c.y - m_top_right.y) * m_factor_y), m_height - 1);
+            const int n = y * m_width + x;
+            ++m_node_count[n];
+        }
+    }
+
+public:
+
+    NodeDensityHandler(Options& options) :
+        m_options(options),
+        m_projection(options.srs),
+        m_width(options.width),
+        m_height(options.height),
+        m_bottom_left(m_projection(options.box.bottom_left())),
+        m_top_right(m_projection(options.box.top_right())),
+        m_factor_x(m_width  / (m_top_right.x - m_bottom_left.x)),
+        m_factor_y(- m_height / (m_top_right.y - m_bottom_left.y)),
+        m_node_count(new node_count_type[m_width * m_height]) {
+    }
+
+    void node(const osmium::Node& node) {
+        record_location(node.location());
+    }
+
+    void write_to_file() {
+        m_options.vout << "Maximum node count per pixel: " << *std::max_element(&m_node_count[0], &m_node_count[m_width * m_height]) << "\n";
+
+        GDALAllRegister();
+
+        GDALDriver* driver = GetGDALDriverManager()->GetDriverByName("GTiff");
+        if (!driver) {
+            std::cerr << "Can't initalize GDAL GTiff driver.\n";
+            exit(return_code::fatal);
+        }
+
+        std::vector<std::string> options;
+        options.push_back("COMPRESS=" + m_options.compression_format);
+        options.push_back("TILED=YES");
+
+        auto dataset_options = std::unique_ptr<char*[]>(new char*[options.size()+1]);
+        std::transform(options.begin(), options.end(), dataset_options.get(), [&](const std::string& s) {
+            return const_cast<char*>(s.data());
+        });
+        dataset_options[options.size()] = nullptr;
+
+        GDALDataset* dataset = driver->Create(m_options.output_filename.c_str(), m_width, m_height, 1, GDT_UInt32, dataset_options.get());
+        if (!dataset) {
+            std::cerr << "Can't create output file '" << m_options.output_filename <<"'.\n";
+            exit(return_code::error);
+        }
+
+        dataset->SetMetadataItem("TIFFTAG_IMAGEDESCRIPTION", "OpenStreetMap node density");
+        dataset->SetMetadataItem("TIFFTAG_COPYRIGHT", "Copyright OpenStreetMap contributors (http://www.openstreetmap.org/copyright), License: CC-BY-SA (http://creativecommons.org/licenses/by-sa/2.0/)");
+        dataset->SetMetadataItem("TIFFTAG_SOFTWARE", "node_density");
+
+        double geo_transform[6] = {m_bottom_left.x, 1/m_factor_x, 0, m_top_right.y, 0, 1/m_factor_y};
+        dataset->SetGeoTransform(geo_transform);
+
+        {
+            OGRSpatialReference srs;
+            srs.importFromProj4(m_projection.proj_string().c_str());
+            char* wkt = nullptr;
+            srs.exportToWkt(&wkt);
+            dataset->SetProjection(wkt);
+            CPLFree(wkt);
+        }
+
+        GDALRasterBand* band = dataset->GetRasterBand(1);
+        assert(band);
+        if (band->RasterIO(GF_Write, 0, 0, m_width, m_height, m_node_count.get(), m_width, m_height, GDT_UInt32, 0, 0) != CE_None) {
+            std::cerr << "Error writing to output file '" << m_options.output_filename <<"'.\n";
+            exit(return_code::error);
+        }
+
+        if (m_options.build_overview) {
+            int num = std::min(static_cast<int>(std::log2(m_width / 256.0)), 8);
+            int overview_list[] = { 2, 4, 8, 16, 32, 64, 128, 256 };
+            dataset->BuildOverviews("AVERAGE", num, overview_list, 0, nullptr, nullptr, nullptr);
+        }
+
+        GDALClose(dataset);
+    }
+
+}; // class NodeDensityHandler
+
+int main(int argc, char* argv[]) {
+    Options options(argc, argv);
+
+    if (options.input_filename == "-" && options.input_format.empty()) {
+        std::cerr << "When reading from STDIN you have to give the input format with --format, -f.\n";
+        std::cerr << "Use one of: 'pbf', 'osm' (uncompressed XML format), 'osm.bz2' (bz2-compressed XML).\n";
+        exit(return_code::fatal);
+    }
+
+    if (options.epsg == 3857) {
+        bool warning = false;
+        if (options.box.bottom_left().lat() < -osmium::geom::MERCATOR_MAX_LAT) {
+            options.box.bottom_left().set_lat(-osmium::geom::MERCATOR_MAX_LAT);
+            warning = true;
+        }
+        if (options.box.top_right().lat() > osmium::geom::MERCATOR_MAX_LAT) {
+            options.box.top_right().set_lat(osmium::geom::MERCATOR_MAX_LAT);
+            warning = true;
+        }
+        if (warning) {
+            std::cerr << "Warning: Reduced size of bounding box to valid area for Web Mercator (EPSG:3857).\n";
+        }
+    }
+
+    options.vout << "Set to verbose output. (Suppress with --quiet, -q.)\n";
+    options.vout << "Options from command line or defaults:\n";
+    options.vout << "  Input file:               " << options.input_filename << "\n";
+    if (!options.input_format.empty()) {
+        options.vout << "  Input format:             " << options.input_format << "\n";
+    }
+    options.vout << "  Output file:              " << options.output_filename << "\n";
+    if (options.epsg > 0) {
+        options.vout << "  EPSG code for SRS:        " << options.epsg << "\n";
+    }
+    options.vout << "  Spatial reference system: " << options.srs << "\n";
+    options.vout << "  Pixel width:              " << options.width << "\n";
+    options.vout << "  Pixel height:             " << options.height << "\n";
+    options.vout << "  Bounding box:             " << options.box << "\n";
+    options.vout << "  Compression:              " << options.compression_format << "\n";
+    options.vout << "  Build overviews:          " << (options.build_overview ? "yes" : "no") << "\n";
+
+    NodeDensityHandler handler(options);
+
+    osmium::io::File file(options.input_filename, options.input_format);
+    osmium::io::Reader reader(file, osmium::osm_entity_bits::node);
+
+    options.vout << "Counting nodes...\n";
+    osmium::apply(reader, handler);
+    options.vout << "Done.\n";
+
+    options.vout << "Writing image to output file...\n";
+    handler.write_to_file();
+    options.vout << "Done.\n";
+
+    google::protobuf::ShutdownProtobufLibrary();
+}
+
diff --git a/pub_names/.gitignore b/pub_names/.gitignore
new file mode 100644
index 0000000..04d86f0
--- /dev/null
+++ b/pub_names/.gitignore
@@ -0,0 +1 @@
+pub_names
diff --git a/pub_names/CMakeLists.txt b/pub_names/CMakeLists.txt
new file mode 100644
index 0000000..e961a4b
--- /dev/null
+++ b/pub_names/CMakeLists.txt
@@ -0,0 +1,24 @@
+#----------------------------------------------------------------------
+#
+#  Single example osmium-contrib CMakeLists.txt
+#
+#----------------------------------------------------------------------
+project(osmium-pub-names)
+
+cmake_minimum_required(VERSION 2.8.5)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake")
+
+find_package(Boost REQUIRED)
+include_directories(${Boost_INCLUDE_DIRS})
+
+find_package(Osmium REQUIRED COMPONENTS io sparsehash)
+include_directories(${OSMIUM_INCLUDE_DIRS})
+
+include(common)
+
+#----------------------------------------------------------------------
+
+set(PROG pub_names)
+file(GLOB SOURCES *.cpp *.hpp)
+add_executable(${PROG} ${SOURCES})
+target_link_libraries(${PROG} ${Boost_LIBRARIES} ${OSMIUM_LIBRARIES})
diff --git a/pub_names/Makefile b/pub_names/Makefile
new file mode 100644
index 0000000..8f43712
--- /dev/null
+++ b/pub_names/Makefile
@@ -0,0 +1,12 @@
+
+all:
+	mkdir -p build && cd build && cmake .. && $(MAKE)
+
+clean:
+	if test -d build; then cd build && $(MAKE) clean; fi
+
+distclean:
+	rm -fr build
+
+.PHONY: clean distclean
+
diff --git a/pub_names/README.md b/pub_names/README.md
new file mode 100644
index 0000000..87cfd6a
--- /dev/null
+++ b/pub_names/README.md
@@ -0,0 +1,45 @@
+
+# Pub Names
+
+A simple program to show the names of all pubs from the given OSM file.
+
+
+## Prerequisites
+
+You'll need libosmium (http://osmcode.org/libosmium) and its dependencies
+installed first.
+
+
+## Building
+
+Osmium-contrib uses CMake for its builds. For Unix/Linux systems a simple
+Makefile wrapper is provided to make the build even easier.
+
+To build just type `make`. Results will be in the `build` subdirectory.
+
+Or you can go the long route explicitly calling CMake as follows:
+
+```
+mkdir build
+cd build
+cmake ..
+make
+```
+
+
+## Running
+
+Run the program with an OSM file as its only argument:
+
+`pub_names ireland.osm.pbf`
+
+
+## License
+
+This program is released into the Public Domain.
+
+
+## Author
+
+Jochen Topf (http://jochentopf.com/)
+
diff --git a/pub_names/pub_names.cpp b/pub_names/pub_names.cpp
new file mode 100755
index 0000000..a5bfa16
--- /dev/null
+++ b/pub_names/pub_names.cpp
@@ -0,0 +1,46 @@
+
+// The code in this file is released into the Public Domain.
+
+#include <iostream>
+
+#include <osmium/io/any_input.hpp>
+#include <osmium/handler.hpp>
+#include <osmium/visitor.hpp>
+
+class NamesHandler : public osmium::handler::Handler {
+
+    void output_pubs(const osmium::OSMObject& object) {
+        const char* amenity = object.tags()["amenity"];
+        if (amenity && !strcmp(amenity, "pub")) {
+            const char* name = object.tags()["name"];
+            if (name) {
+                std::cout << name << std::endl;
+            }
+        }
+    }
+
+public:
+
+    void node(const osmium::Node& node) {
+        output_pubs(node);
+    }
+
+    void way(const osmium::Way& way) {
+        output_pubs(way);
+    }
+
+};
+
+int main(int argc, char* argv[]) {
+    if (argc != 2) {
+        std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
+        exit(1);
+    }
+
+    NamesHandler names_handler;
+
+    osmium::io::Reader reader(argv[1], osmium::osm_entity_bits::node | osmium::osm_entity_bits::way);
+
+    osmium::apply(reader, names_handler);
+}
+
diff --git a/road_length/.gitignore b/road_length/.gitignore
new file mode 100644
index 0000000..aef0618
--- /dev/null
+++ b/road_length/.gitignore
@@ -0,0 +1 @@
+road_length
diff --git a/road_length/CMakeLists.txt b/road_length/CMakeLists.txt
new file mode 100644
index 0000000..e23d190
--- /dev/null
+++ b/road_length/CMakeLists.txt
@@ -0,0 +1,24 @@
+#----------------------------------------------------------------------
+#
+#  Single example osmium-contrib CMakeLists.txt
+#
+#----------------------------------------------------------------------
+project(osmium-road-length)
+
+cmake_minimum_required(VERSION 2.8.5)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake")
+
+find_package(Boost REQUIRED)
+include_directories(${Boost_INCLUDE_DIRS})
+
+find_package(Osmium REQUIRED COMPONENTS io sparsehash)
+include_directories(${OSMIUM_INCLUDE_DIRS})
+
+include(common)
+
+#----------------------------------------------------------------------
+
+set(PROG road_length)
+file(GLOB SOURCES *.cpp *.hpp)
+add_executable(${PROG} ${SOURCES})
+target_link_libraries(${PROG} ${Boost_LIBRARIES} ${OSMIUM_LIBRARIES})
diff --git a/road_length/Makefile b/road_length/Makefile
new file mode 100644
index 0000000..8f43712
--- /dev/null
+++ b/road_length/Makefile
@@ -0,0 +1,12 @@
+
+all:
+	mkdir -p build && cd build && cmake .. && $(MAKE)
+
+clean:
+	if test -d build; then cd build && $(MAKE) clean; fi
+
+distclean:
+	rm -fr build
+
+.PHONY: clean distclean
+
diff --git a/road_length/README.md b/road_length/README.md
new file mode 100644
index 0000000..f266e62
--- /dev/null
+++ b/road_length/README.md
@@ -0,0 +1,46 @@
+
+# Road Length
+
+A simple program to calculate the length of the road network (everything tagged
+highway=*) from the given OSM file.
+
+
+## Prerequisites
+
+You'll need libosmium (http://osmcode.org/libosmium) and its dependencies
+installed first.
+
+
+## Building
+
+Osmium-contrib uses CMake for its builds. For Unix/Linux systems a simple
+Makefile wrapper is provided to make the build even easier.
+
+To build just type `make`. Results will be in the `build` subdirectory.
+
+Or you can go the long route explicitly calling CMake as follows:
+
+```
+mkdir build
+cd build
+cmake ..
+make
+```
+
+
+## Running
+
+Run the program with an OSM file as its only argument:
+
+`road_length germany.osm.pbf`
+
+
+## License
+
+This program is released into the Public Domain.
+
+
+## Author
+
+Jochen Topf (http://jochentopf.com/)
+
diff --git a/road_length/road_length.cpp b/road_length/road_length.cpp
new file mode 100755
index 0000000..36e3349
--- /dev/null
+++ b/road_length/road_length.cpp
@@ -0,0 +1,45 @@
+
+// The code in this file is released into the Public Domain.
+
+#include <iostream>
+
+#include <osmium/io/any_input.hpp>
+#include <osmium/geom/haversine.hpp>
+#include <osmium/visitor.hpp>
+
+#include <osmium/index/map/sparse_mem_array.hpp>
+#include <osmium/handler/node_locations_for_ways.hpp>
+typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
+typedef osmium::handler::NodeLocationsForWays<index_type> location_handler_type;
+
+struct RoadLengthHandler : public osmium::handler::Handler {
+
+    double length = 0;
+
+    void way(const osmium::Way& way) {
+        const char* highway = way.tags()["highway"];
+        if (highway) {
+            length += osmium::geom::haversine::distance(way.nodes());
+        }
+    }
+
+};
+
+int main(int argc, char* argv[]) {
+    if (argc != 2) {
+        std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
+        exit(1);
+    }
+
+    osmium::io::Reader reader(argv[1], osmium::osm_entity_bits::node | osmium::osm_entity_bits::way);
+
+    index_type index;
+    location_handler_type location_handler(index);
+
+    RoadLengthHandler road_length_handler;
+
+    osmium::apply(reader, location_handler, road_length_handler);
+
+    std::cout << "Length: " << road_length_handler.length / 1000 << " km\n";
+}
+

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



More information about the Pkg-grass-devel mailing list