[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