[osm2pgrouting] 01/06: New upstream version 2.3.3

Bas Couwenberg sebastic at debian.org
Tue Dec 19 06:49:31 UTC 2017


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

sebastic pushed a commit to branch master
in repository osm2pgrouting.

commit ac9ae0fe0437ccc202b8188a80fd85396f117c9c
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Tue Dec 19 07:30:18 2017 +0100

    New upstream version 2.3.3
---
 .gitignore                                         |   6 +
 .travis.yml                                        |  17 +-
 CMakeLists.txt                                     |  62 +++-
 NEWS                                               |   4 +
 Readme.md                                          |   5 +-
 cmake/FindOsmium.cmake                             | 370 +++++++++++++++++++++
 include/database/Export2DB.h                       |   1 +
 include/osm_elements/OSMDocument.h                 |   4 +-
 include/osm_elements/Relation.h                    |   2 +
 src/database/Export2DB.cpp                         |  98 ++++--
 src/database/osm_ways_config.cpp                   |   6 +-
 src/database/table_management.cpp                  |  47 ++-
 src/osm_elements/OSMDocument.cpp                   |  16 +-
 src/osm_elements/Relation.cpp                      |  13 +-
 src/osm_elements/Way.cpp                           |  12 +-
 src/osm_elements/osm2pgrouting.cpp                 |   7 +-
 src/osm_elements/osm_tag.cpp                       |   2 +
 src/parser/OSMDocumentParserCallback.cpp           |  14 +-
 tools/data/getdata.sh                              |  36 ++
 CMakeLists.txt => tools/osmium/CMakeLists.txt      |  53 +--
 tools/osmium/README.md                             |  13 +
 tools/osmium/cmake/FindLibPQXX.cmake               |  43 +++
 tools/osmium/cmake/FindOsmium.cmake                | 369 ++++++++++++++++++++
 tools/osmium/cmake/FindPostgreSQL.cmake            |  74 +++++
 .../osmium/include/collectors/turn_restrictions.h  |  91 +++++
 tools/osmium/include/quotes_handling.cpp           | 310 +++++++++++++++++
 tools/osmium/include/utilities/quotes_handling.h   |  40 +++
 tools/osmium/restrictions.sql                      |  53 +++
 tools/osmium/restrictions_end.sql                  |  27 ++
 tools/osmium/src/collectors/turn_restriccions.cpp  | 227 +++++++++++++
 tools/osmium/src/getrestrictions.cpp               | 136 ++++++++
 tools/osmium/src/utilities/quotes_handling.cpp     |  78 +++++
 32 files changed, 2114 insertions(+), 122 deletions(-)

diff --git a/.gitignore b/.gitignore
index 001d9f8..1f14bae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,8 +8,14 @@ fix_typos
 *.o
 *.out
 *.osm
+*.osm.bz2
+*.osm.gz
+*.tar.gz
 *~
 .project
 .cproject
 .vagrant
 run.sh
+LOG.txt
+.directory
+*.swp
diff --git a/.travis.yml b/.travis.yml
index c129de1..976175d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,20 +7,13 @@
 
 #choose precise or trusty
 
-#group: edge
-#dist: trusty    
-
-#dist: precise
-
+dist: trusty
 
 language: cpp
 
 compiler:
     - gcc
 
-#notifications:
-#  email:
-#    on_failure: project at pgrouting.org
 
 env: POSTGRESQL_VERSION=9.6   PG_USER=postgres DIST=precise
       
@@ -30,22 +23,16 @@ matrix:
 
     - os: linux
       sudo: required
-      dist: trusty
-      group: edge
       env: POSTGRESQL_VERSION=9.6   PG_USER=postgres DIST=trusty
 
 
     - os: linux
       sudo: required
-      dist: trusty
-      group: edge
       env: POSTGRESQL_VERSION=9.5   PG_USER=postgres DIST=trusty
 
 
     - os: linux
       sudo: required
-      dist: trusty
-      group: edge
       env: POSTGRESQL_VERSION=9.4   PG_USER=postgres DIST=trusty
 
 
@@ -54,7 +41,7 @@ matrix:
 addons:
   apt:
     sources:
-      - - ubuntu-toolchain-r-test
+      - ubuntu-toolchain-r-test
       # For cmake
       - kubuntu-backports
       - boost-latest
diff --git a/CMakeLists.txt b/CMakeLists.txt
index de75fb8..b479f1f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,13 +1,20 @@
 PROJECT(osm2pgrouting)
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 
-set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
-set (SHARE_DIR "/usr/share/osm2pgrouting")
+if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} )
+    message(FATAL_ERROR "In-source builds not allowed.
+    Please make a new directory (called a build directory) and run CMake from there.
+    You may need to remove CMakeCache.txt." )
+endif()
+
+LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+SET(SHARE_DIR "/usr/share/osm2pgrouting")
 
 FIND_PACKAGE(PostgreSQL REQUIRED)
 find_package(LibPQXX REQUIRED)
 FIND_PACKAGE(EXPAT REQUIRED)
 
+
 FIND_PACKAGE(Boost)
 if(Boost_INCLUDE_DIRS)
     message(STATUS "Boost headers were found here: ${Boost_INCLUDE_DIRS}")
@@ -19,9 +26,58 @@ FIND_PACKAGE(Boost COMPONENTS program_options REQUIRED)
 
 FILE(GLOB osm2pgrouting_lib_SOURCES "${CMAKE_SOURCE_DIR}/src/*/*.cpp")
 
-set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FILE_OFFSET_BITS=64 -std=c++0x")
+#---------------------------------------------
+# C++ Compiler requirements
+#---------------------------------------------
+set(GNU_CXX_MINIMUM_VERSION "4.6")
+set(MSVC_CXX_MINIMUM_VERSION "18.0")
+
+include(CheckCXXCompilerFlag)
+
+CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
+CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
+CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+    if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS GNU_CXX_MINIMUM_VERSION)
+        message(FATAL_ERROR "GCC version must be at least ${GNU_CXX_MINIMUM_VERSION}!
+        Found version ${CMAKE_CXX_COMPILER_VERSION}")
+    endif()
+elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
+    if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS MSVC_CXX_MINIMUM_VERSION)
+        message(FATAL_ERROR "MSVC version must be at least ${MSVC_CXX_MINIMUM_VERSION}!")
+    endif()
+else()
+    message(STATUS "Unknown compiler minimum version for ${CMAKE_CXX_COMPILER_ID}")
+endif()
+
+if(COMPILER_SUPPORTS_CXX14)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
+    message(STATUS "Using  -std=c++14.")
+elseif(COMPILER_SUPPORTS_CXX11)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+    message(STATUS "Using  -std=c++11.")
+elseif(COMPILER_SUPPORTS_CXX0X)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+    message(STATUS "Using  -std=c++0x.")
+else()
+    message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++0x or C++11 or C++14 flags support.")
+endif()
+
+
+
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FILE_OFFSET_BITS=64")
 set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wconversion -pedantic -Wextra  -frounding-math -Wno-deprecated -fmax-errors=10")
 
+if(WIN32 AND MSVC)
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_DEPRECATE")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_SCL_SECURE_NO_DEPRECATE")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_SCL_SECURE_NO_WARNINGS")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_NONSTDC_NO_DEPRECATE")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -EHsc")
+endif()
+
+#--------------------------------------------------------
 
 set (OSM2PGROUTING_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/include")
 message(STATUS "LIBPQXX_INCLUDE_DIRS: ${LIBPQXX_INCLUDE_DIRS}")
diff --git a/NEWS b/NEWS
index 9fbe749..da5bbc3 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+osm2pgRouting 2.3.3
+* Fix: wrong assumption in implied_oneWay() function
+* Fix: regression on 2.3.2: fixed hstore refs handling
+
 osm2pgRouting 2.3.2
 
 * Fix: Only on linux: use the wc command to count lines
diff --git a/Readme.md b/Readme.md
index b4316dc..12554b0 100644
--- a/Readme.md
+++ b/Readme.md
@@ -22,7 +22,7 @@ See in the documentation of the pgrouting website for more information: http://p
 
 ## Installation
 
-For compiling this tool, you will need boost, libpq, expat and cmake:
+For compiling this tool, you will need boost, libpqxx, expat and cmake:
 Then just type the following in the root directory:
 
 ```
@@ -42,6 +42,9 @@ sudo apt-get install libboost-program-options-dev
 sudo apt install libpqxx-dev
 ```
 
+**Note:** FindLibPQXX.cmake does not find the version of libpqxx, but its documentation says C++11 is needed for the latests versions.
+
+
 If you have libraries installed in non-standard locations, you might need to pass in parameters to cmake. Commonly useful parameters are
 
 CMAKE options:
diff --git a/cmake/FindOsmium.cmake b/cmake/FindOsmium.cmake
new file mode 100644
index 0000000..adc457f
--- /dev/null
+++ b/cmake/FindOsmium.cmake
@@ -0,0 +1,370 @@
+#----------------------------------------------------------------------
+#
+#  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 [version] REQUIRED COMPONENTS <XXX>)
+#      include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
+#
+#    The version number is optional. If it is not set, any version of
+#    libosmium will do.
+#
+#    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.
+#
+#----------------------------------------------------------------------
+
+# This is the list of directories where we look for osmium and protozero
+# includes.
+set(_osmium_include_path
+        ../libosmium
+        ~/Library/Frameworks
+        /Library/Frameworks
+        /opt/local # DarwinPorts
+        /opt
+)
+
+# Look for the header file.
+find_path(OSMIUM_INCLUDE_DIR osmium/version.hpp
+    PATH_SUFFIXES include
+    PATHS ${_osmium_include_path}
+)
+
+# Check libosmium version number
+if(Osmium_FIND_VERSION)
+    file(STRINGS "${OSMIUM_INCLUDE_DIR}/osmium/version.hpp" _libosmium_version_define REGEX "#define LIBOSMIUM_VERSION_STRING")
+    if("${_libosmium_version_define}" MATCHES "#define LIBOSMIUM_VERSION_STRING \"([0-9.]+)\"")
+        set(_libosmium_version "${CMAKE_MATCH_1}")
+    else()
+        set(_libosmium_version "unknown")
+    endif()
+endif()
+
+set(OSMIUM_INCLUDE_DIRS "${OSMIUM_INCLUDE_DIR}")
+
+#----------------------------------------------------------------------
+#
+#  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(ZLIB)
+    find_package(Threads)
+
+    message(STATUS "Looking for protozero")
+    find_path(PROTOZERO_INCLUDE_DIR protozero/version.hpp
+        PATH_SUFFIXES include
+        PATHS ${_osmium_include_path}
+              ${OSMIUM_INCLUDE_DIR}
+    )
+    if(PROTOZERO_INCLUDE_DIR)
+        message(STATUS "Looking for protozero - found")
+    else()
+        message(STATUS "Looking for protozero - not found")
+    endif()
+
+    list(APPEND OSMIUM_EXTRA_FIND_VARS ZLIB_FOUND Threads_FOUND PROTOZERO_INCLUDE_DIR)
+    if(ZLIB_FOUND AND Threads_FOUND AND PROTOZERO_INCLUDE_DIR)
+        list(APPEND OSMIUM_PBF_LIBRARIES
+            ${ZLIB_LIBRARIES}
+            ${CMAKE_THREAD_LIBS_INIT}
+        )
+        if(WIN32)
+            # This is needed for the ntohl() function
+            list(APPEND OSMIUM_PBF_LIBRARIES ws2_32)
+        endif()
+        list(APPEND OSMIUM_INCLUDE_DIRS
+            ${ZLIB_INCLUDE_DIR}
+            ${PROTOZERO_INCLUDE_DIR}
+        )
+    else()
+        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)
+
+    list(APPEND OSMIUM_EXTRA_FIND_VARS EXPAT_FOUND BZIP2_FOUND ZLIB_FOUND Threads_FOUND)
+    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()
+        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)
+
+    list(APPEND OSMIUM_EXTRA_FIND_VARS GEOS_INCLUDE_DIR GEOS_LIBRARY)
+    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()
+        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)
+
+    list(APPEND OSMIUM_EXTRA_FIND_VARS GDAL_FOUND)
+    if(GDAL_FOUND)
+        list(APPEND OSMIUM_LIBRARIES ${GDAL_LIBRARIES})
+        list(APPEND OSMIUM_INCLUDE_DIRS ${GDAL_INCLUDE_DIRS})
+    else()
+        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)
+
+    list(APPEND OSMIUM_EXTRA_FIND_VARS PROJ_INCLUDE_DIR PROJ_LIBRARY)
+    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()
+        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)
+
+    list(APPEND OSMIUM_EXTRA_FIND_VARS SPARSEHASH_INCLUDE_DIR)
+    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++.
+        if(NOT CMAKE_VERSION VERSION_LESS 3.0)
+           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)
+        else()
+           set(SPARSETABLE_SIZE_TYPE ${CMAKE_SIZEOF_VOID_P})
+        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()
+        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_EXTRA_FIND_VARS)
+    list(REMOVE_DUPLICATES OSMIUM_EXTRA_FIND_VARS)
+endif()
+# Handle the QUIETLY and REQUIRED arguments and the optional version check
+# 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 ${OSMIUM_EXTRA_FIND_VARS}
+                                  VERSION_VAR _libosmium_version)
+unset(OSMIUM_EXTRA_FIND_VARS)
+
+#----------------------------------------------------------------------
+#
+#  A function for setting the -pthread option in compilers/linkers
+#
+#----------------------------------------------------------------------
+function(set_pthread_on_target _target)
+    if(NOT MSVC)
+        set_target_properties(${_target} PROPERTIES COMPILE_FLAGS "-pthread")
+        if(NOT APPLE)
+            set_target_properties(${_target} PROPERTIES LINK_FLAGS "-pthread")
+        endif()
+    endif()
+endfunction()
+
+#----------------------------------------------------------------------
+#
+#  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)
+
+    # Disable warning C4503: "decorated name length exceeded, name was truncated"
+    # there are more than 150 of generated names in libosmium longer than 4096 symbols supported in MSVC
+    add_definitions(-wd4503)
+
+    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" 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/include/database/Export2DB.h b/include/database/Export2DB.h
index c83cdad..442e1ce 100644
--- a/include/database/Export2DB.h
+++ b/include/database/Export2DB.h
@@ -110,6 +110,7 @@ class Export2DB {
      void dropTables() const;
      void createFKeys() const;
      void process_pois() const;
+     bool exists(const std::string &table) const;
 
  private:
 
diff --git a/include/osm_elements/OSMDocument.h b/include/osm_elements/OSMDocument.h
index 62d4a2c..4bb05e6 100644
--- a/include/osm_elements/OSMDocument.h
+++ b/include/osm_elements/OSMDocument.h
@@ -75,7 +75,7 @@ class OSMDocument {
     void AddNode(const Node &n);
     void AddWay(const Way &w);
     void AddRelation(const Relation &r);
-    void endOfFile() const;
+    void endOfFile();
 
     //! find node by using an ID
     bool has_node(int64_t nodeRefId) const;
@@ -145,6 +145,8 @@ class OSMDocument {
     Ways m_ways;
     //! parsed relations
     Relations  m_relations;
+    bool       m_relPending;
+    bool       m_waysPending;
 
     const Configuration& m_rConfig;
     po::variables_map m_vm;
diff --git a/include/osm_elements/Relation.h b/include/osm_elements/Relation.h
index e73bdf5..3d89ba0 100644
--- a/include/osm_elements/Relation.h
+++ b/include/osm_elements/Relation.h
@@ -71,6 +71,8 @@ class Relation : public Element{
      int64_t add_member(const char **atts);
      std::string members_str() const;
 
+     friend std::ostream& operator<<(std::ostream &os, const Relation &r);
+
  private:
      std::vector<int64_t> m_WayRefs;
 };
diff --git a/src/database/Export2DB.cpp b/src/database/Export2DB.cpp
index 8413d5b..1877dd2 100644
--- a/src/database/Export2DB.cpp
+++ b/src/database/Export2DB.cpp
@@ -110,23 +110,48 @@ Export2DB::install_postGIS() const {
 
 
 // /////////////////////
+
+
+bool Export2DB::exists(const std::string &table) const {
+    try {
+        pqxx::connection db_conn(conninf);
+        pqxx::work Xaction(db_conn);
+
+        Xaction.exec(std::string("SELECT '") + table + "'::regclass");
+        std::cout << "TABLE: " << vertices().addSchema() << " already exists.\n";
+        return true;
+    } catch (const std::exception &e) {
+        return false;
+    }
+}
+
+
+
 void Export2DB::createTables() const {
-    //  the following are particular of the file tables
     try {
         pqxx::connection db_conn(conninf);
         pqxx::work Xaction(db_conn);
 
-        Xaction.exec(vertices().create());
-        std::cout << "TABLE: " << vertices().addSchema() << " created ... OK.\n";
+        if (!exists(vertices().addSchema())) {
+            Xaction.exec(vertices().create());
+            std::cout << "TABLE: " << vertices().addSchema() << " created ... OK.\n";
+        }
 
-        Xaction.exec(ways().create());
-        std::cout << "TABLE: " << ways().addSchema() << " created ... OK.\n";
+        if (!exists(ways().addSchema())) {
+            Xaction.exec(ways().create());
+            std::cout << "TABLE: " << ways().addSchema() << " created ... OK.\n";
+        }
 
-        Xaction.exec(pois().create());
-        std::cout << "TABLE: " << pois().addSchema() << " created ... OK.\n";
+        if (!exists(pois().addSchema())) {
+            Xaction.exec(pois().create());
+            std::cout << "TABLE: " << pois().addSchema() << " created ... OK.\n";
+        }
+
+        if (!exists(configuration().addSchema())) {
+            Xaction.exec(configuration().create());
+            std::cout << "TABLE: " << configuration().addSchema() << " created ... OK.\n";
+        }
 
-        Xaction.exec(configuration().create());
-        std::cout << "TABLE: " << configuration().addSchema() << " created ... OK.\n";
 
         Xaction.commit();
     } catch (const std::exception &e) {
@@ -136,27 +161,33 @@ void Export2DB::createTables() const {
     }
 
     if (m_vm.count("addnodes")) {
-    try {
-        pqxx::connection db_conn(conninf);
-        pqxx::work Xaction(db_conn);
-        /*
-         * optional tables
-         */
-        Xaction.exec(osm_nodes().create());
-        std::cout << "TABLE: " << osm_nodes().addSchema() << " created ... OK.\n";
+        try {
+            pqxx::connection db_conn(conninf);
+            pqxx::work Xaction(db_conn);
+            /*
+             * optional tables
+             */
+            if (!exists(osm_nodes().addSchema())) {
+                Xaction.exec(osm_nodes().create());
+                std::cout << "TABLE: " << osm_nodes().addSchema() << " created ... OK.\n";
+            }
 
-        Xaction.exec(osm_ways().create());
-        std::cout << "TABLE: " << osm_ways().addSchema() << " created ... OK.\n";
+            if (!exists(osm_ways().addSchema())) {
+                Xaction.exec(osm_ways().create());
+                std::cout << "TABLE: " << osm_ways().addSchema() << " created ... OK.\n";
+            }
 
-        Xaction.exec(osm_relations().create());
-        std::cout << "TABLE: " << osm_relations().addSchema() << " created ... OK.\n";
+            if (!exists(osm_relations().addSchema())) {
+                Xaction.exec(osm_relations().create());
+                std::cout << "TABLE: " << osm_relations().addSchema() << " created ... OK.\n";
+        }
 
         Xaction.commit();
-    } catch (const std::exception &e) {
-        std::cerr <<  "\n" << e.what() << std::endl;
-        std::cerr <<  "WARNING: could not create osm-*  tables" << std::endl;
-        std::cerr <<  "   Insertions on osm_* tables are going to be ignored" << std::endl;
-    }
+        } catch (const std::exception &e) {
+            std::cerr <<  "\n" << e.what() << std::endl;
+            std::cerr <<  "WARNING: could not create osm-*  tables" << std::endl;
+            std::cerr <<  "   Insertions on osm_* tables are going to be ignored" << std::endl;
+        }
     }
 }
 
@@ -543,7 +574,6 @@ Export2DB::execute(const std::string sql) const {
  *
  */
 void Export2DB::createFKeys() const {
-
     /*
      * configuration:
      */
@@ -576,6 +606,7 @@ void Export2DB::createFKeys() const {
     execute(pois().unique("osm_id"));
 }
 
+
 void Export2DB::process_pois() const {
     if (!m_vm.count("addnodes")) return;
 
@@ -599,11 +630,14 @@ void Export2DB::process_pois() const {
     /* osm2pgr_pois_update */
     execute(pois().sql(4));
 
-    std::cout << "\nTo process pointsOfInterest table:"
-    "\nosm2pgr_pois_update(radius default 200, within default 50)\n"
-    "\n  - Using areas of (radius)mts on POIS"
-    "\n  - Using edges that are at least (within) mts of each POI"
-    "\nPOIS that do not have a closest edge is considered as too far\n";
+    std::cout << "\nTo process pointsOfInterest table:\n"
+#if 0 //TODO
+        << m_schema << (m_schema == "" ? "" :  ".")
+#endif
+        << "osm2pgr_pois_update(radius default 200, within default 50)\n"
+        "\n  - Using areas of (radius)mts on POIS"
+        "\n  - Using edges that are at least (within) mts of each POI"
+        "\nPOIS that do not have a closest edge is considered as too far\n";
 
 
     return;
diff --git a/src/database/osm_ways_config.cpp b/src/database/osm_ways_config.cpp
index 7140876..1f6f636 100644
--- a/src/database/osm_ways_config.cpp
+++ b/src/database/osm_ways_config.cpp
@@ -26,7 +26,7 @@ namespace osm2pgr {
 
 /*
  * configuring TABLE osm_ways
- */ 
+ */
 
 
 Table
@@ -44,9 +44,9 @@ Tables::osm_ways_config() const {
             /* standard column creation string */
             std::string(
                 " osm_id bigint PRIMARY KEY"
-                //" , members hstore"
+                " , members hstore"
                 + (m_vm.count("attributes")  && m_vm.count("addnodes") ?
-                    (std::string(", attributes hstore")) 
+                    (std::string(", attributes hstore"))
                     : "")
                 + (m_vm.count("tags")  && m_vm.count("addnodes") ?
                     (std::string(", tags hstore"))
diff --git a/src/database/table_management.cpp b/src/database/table_management.cpp
index b30b636..1a46215 100644
--- a/src/database/table_management.cpp
+++ b/src/database/table_management.cpp
@@ -127,7 +127,7 @@ Table::create() const {
 
 std::string
 Table::drop() const {
-    return "DROP TABLE IF EXISTS " + addSchema() + ";";
+    return "DROP TABLE IF EXISTS " + addSchema() + " CASCADE;";
 }
 
 
@@ -203,8 +203,12 @@ Tables::Tables(const  po::variables_map &vm) :
     m_osm_ways(osm_ways_config()),
     m_osm_relations(osm_relations_config())
 {
+    auto m_schema(vm["schema"].as<string>());
+    m_schema += (m_schema == "" ? "" :  ".");
     m_points_of_interest.add_sql(
-            "\nCREATE OR REPLACE FUNCTION osm2pgr_pois_update_part_of_topology()"
+            "\nCREATE OR REPLACE FUNCTION "
+            + m_schema
+            + "osm2pgr_pois_update_part_of_topology()"
             "\nRETURNS BIGINT AS"
             "\n$$"
             "\n-----------------------------------------------------------------"
@@ -224,13 +228,15 @@ Tables::Tables(const  po::variables_map &vm) :
             + "\nEND;"
             + "\n$$"
             + "\nLANGUAGE plpgsql;"
-            + "\nCOMMENT ON FUNCTION osm2pgr_pois_update_part_of_topology()"
+            + "\nCOMMENT ON FUNCTION " + m_schema + "osm2pgr_pois_update_part_of_topology()"
             + "\n  IS 'osm2pgrouting generated function';"
             );
 
 
     m_points_of_interest.add_sql(
-            "CREATE OR REPLACE FUNCTION osm2pgr_pois_update_not_part_of_topology(radius FLOAT, within FLOAT, tooFar BIGINT[])"
+            "CREATE OR REPLACE FUNCTION "
+            + m_schema
+            +"osm2pgr_pois_update_not_part_of_topology(radius FLOAT, within FLOAT, tooFar BIGINT[])"
             "\n RETURNS BIGINT AS"
             "\n $$"
             "\n-----------------------------------------------------------------"
@@ -300,12 +306,14 @@ Tables::Tables(const  po::variables_map &vm) :
             +"\n END;"
             +"\n $$"
             +"\n LANGUAGE plpgsql;"
-            +"\nCOMMENT ON FUNCTION osm2pgr_pois_update_not_part_of_topology(float,float,bigint[])"
+            +"\nCOMMENT ON FUNCTION " + m_schema + "osm2pgr_pois_update_not_part_of_topology(float,float,bigint[])"
             + "\n  IS 'osm2pgrouting generated function';"
             );
 
     m_points_of_interest.add_sql(
-            "CREATE OR REPLACE FUNCTION osm2pgr_pois_find_side()"
+            "CREATE OR REPLACE FUNCTION "
+            + m_schema
+            +"osm2pgr_pois_find_side()"
             "\n RETURNS VOID AS"
             "\n $$"
             "\n WITH "
@@ -354,12 +362,14 @@ Tables::Tables(const  po::variables_map &vm) :
             + "\n WHERE last.pid = " + pois().addSchema() + ".pid;"
             +"\n $$"
             +"\n LANGUAGE sql;"
-            +"\nCOMMENT ON FUNCTION osm2pgr_pois_find_side()"
+            +"\nCOMMENT ON FUNCTION " + m_schema + "osm2pgr_pois_find_side()"
             + "\n  IS 'osm2pgrouting generated function';"
             );
 
     m_points_of_interest.add_sql(
-            "CREATE OR REPLACE FUNCTION osm2pgr_pois_new_geom()"
+            "CREATE OR REPLACE FUNCTION "
+            + m_schema
+            +"osm2pgr_pois_new_geom()"
             "\n RETURNS VOID AS"
             "\n $$"
             "\n UPDATE " + pois().addSchema()
@@ -371,14 +381,15 @@ Tables::Tables(const  po::variables_map &vm) :
             + "\n         WHERE vertex_id IS NOT NULL;"
             + "\n $$"
             + "\n LANGUAGE sql;"
-            +"\nCOMMENT ON FUNCTION osm2pgr_pois_new_geom()"
+            +"\nCOMMENT ON FUNCTION " + m_schema + "osm2pgr_pois_new_geom()"
             + "\n  IS 'osm2pgrouting generated function';"
             );
 
 
     m_points_of_interest.add_sql(
-            "\nCREATE OR REPLACE FUNCTION osm2pgr_pois_update(radius FLOAT DEFAULT 200, within FLOAT DEFAULT 50)"
-
+            "\nCREATE OR REPLACE FUNCTION "
+            + m_schema
+            +"osm2pgr_pois_update(radius FLOAT DEFAULT 200, within FLOAT DEFAULT 50)"
             "\n RETURNS BIGINT AS"
             "\n $$"
             "\n-----------------------------------------------------------------"
@@ -401,16 +412,16 @@ Tables::Tables(const  po::variables_map &vm) :
             "\n    factor FLOAT = 0.5;"
             "\n    tooFar BIGINT[];"
             "\n BEGIN"
-            "\n    total = osm2pgr_pois_update_part_of_topology();"
+            "\n    total = " + m_schema + "osm2pgr_pois_update_part_of_topology();"
 
             "\n    SELECT count(*) FROM " + pois().addSchema()
             +"\n    WHERE vertex_id IS NULL AND edge_id IS NULL"
             +"\n    INTO rec; "
 
             +"\n    FOR i IN 1..rec.count LOOP"
-            +"\n        curr_tot = osm2pgr_pois_update_not_part_of_topology(radius, within, tooFar);"
+            +"\n        curr_tot = " + m_schema + "osm2pgr_pois_update_not_part_of_topology(radius, within, tooFar);"
 
-            +"          RAISE NOTICE '%: Updated % points of Interest', i, curr_tot;"
+            +"\n        RAISE NOTICE '%: Updated % points of Interest', i, curr_tot;"
             +"\n        total := total + curr_tot;"
             +"\n        IF (curr_tot = 0) THEN"
             +"\n            SELECT pid FROM " + pois().addSchema()
@@ -426,15 +437,15 @@ Tables::Tables(const  po::variables_map &vm) :
             +"\n            EXIT WHEN rec.count = 0;"
             +"\n        END IF;"
             +"\n    END LOOP;"
-            +"\n    PERFORM osm2pgr_pois_find_side();"
-            +"\n    PERFORM osm2pgr_pois_new_geom();"
+            +"\n    PERFORM " + m_schema + "osm2pgr_pois_find_side();"
+            +"\n    PERFORM " + m_schema + "osm2pgr_pois_new_geom();"
 
             +"\n    return total;"
             +"\n END;"
             +"\n $$"
             +"\n LANGUAGE plpgsql;"
-            +"\nCOMMENT ON FUNCTION osm2pgr_pois_update(float, float)"
-            + "\n  IS 'osm2pgrouting generated function. osm2pgr_pois_update(radius, within)\nworking on areas of (radius)mts\nOn edges that are at least (within) mts of each POI';"
+            +"\nCOMMENT ON FUNCTION " + m_schema + "osm2pgr_pois_update(float, float)"
+            + "\n  IS 'osm2pgrouting generated function. " + m_schema + "osm2pgr_pois_update(radius, within)\nworking on areas of (radius)mts\nOn edges that are at least (within) mts of each POI';"
             );
 
 
diff --git a/src/osm_elements/OSMDocument.cpp b/src/osm_elements/OSMDocument.cpp
index bc602c3..697344f 100644
--- a/src/osm_elements/OSMDocument.cpp
+++ b/src/osm_elements/OSMDocument.cpp
@@ -46,6 +46,8 @@ OSMDocument::OSMDocument(
         const po::variables_map &vm,
         const Export2DB &db_conn,
         size_t lines) :
+    m_relPending(false),
+    m_waysPending(true),
     m_rConfig(config),
     m_vm(vm),
     m_db_conn(db_conn),
@@ -110,25 +112,29 @@ void OSMDocument::AddWay(const Way &w) {
 
 void
 OSMDocument::AddRelation(const Relation &r) {
-    if (m_vm.count("addnodes") && m_relations.empty()) {
+    if (m_vm.count("addnodes") && m_waysPending) {
+        m_waysPending = false;
         wait_child();
         osm_table_export(m_ways, "osm_ways");
         std::cout << "\nFinal osm_ways:\t" << m_ways.size() << "\n";
     }
 
+    m_relPending = true;
+    m_relations.push_back(r);
     if (m_vm.count("addnodes")) {
         if (m_relations.size() % m_chunk_size == 0) {
             wait_child();
-            std::cout << "\rCurrent osm_relations:\t" << m_relations.size();
+            std::cout << "Current osm_relations:\t" << m_relations.size();
             osm_table_export(m_relations, "osm_relations");
+            m_relPending = false;
         }
     }
-    m_relations.push_back(r);
 }
 
 void
-OSMDocument::endOfFile() const {
-    if (m_vm.count("addnodes")) {
+OSMDocument::endOfFile() {
+    if (m_vm.count("addnodes") && m_relPending == true) {
+        m_relPending = false;
         wait_child();
         std::cout << "\nFinal osm_relations:\t" << m_relations.size();
         osm_table_export(m_relations, "osm_relations");
diff --git a/src/osm_elements/Relation.cpp b/src/osm_elements/Relation.cpp
index d7f2228..35dc032 100644
--- a/src/osm_elements/Relation.cpp
+++ b/src/osm_elements/Relation.cpp
@@ -33,6 +33,9 @@ Relation::Relation(const char **atts) :
 
 int64_t
 Relation::add_member(const char **atts) {
+#if 0
+    std::cout << " --> " << __PRETTY_FUNCTION__ << "\n";
+#endif
     auto **attribut = atts;
     std::string type;
     int64_t osm_id(0);
@@ -54,6 +57,10 @@ Relation::add_member(const char **atts) {
         }
     }
     m_WayRefs.push_back(osm_id);
+#if 0
+    std::cout << "members" << members_str() << "\n";
+    std::cout << " <-- " << __PRETTY_FUNCTION__ << "\n";
+#endif
     return osm_id;
 }
 
@@ -65,13 +72,17 @@ Relation::members_str() const {
         /*
          * currently only adding way
          */
-            + "=>\"type=>way,role=>TODO\"" + ",";
+            + "=>\"type=>way\",";
     }
     way_list[way_list.size() -1] = ' ';
 
     return way_list;
 }
 
+std::ostream& operator<<(std::ostream &os, const Relation &r) {
+    os << r.members_str();
+    return os;
+}
 
 }  // end namespace osm2pgr
 
diff --git a/src/osm_elements/Way.cpp b/src/osm_elements/Way.cpp
index 6fa2cf3..87788b9 100644
--- a/src/osm_elements/Way.cpp
+++ b/src/osm_elements/Way.cpp
@@ -40,7 +40,7 @@ Way::Way(const char **atts) :
     Element(atts),
     m_maxspeed_forward(-1),
     m_maxspeed_backward(-1),
-    m_oneWay("UNKNOWN") { 
+    m_oneWay("UNKNOWN") {
     }
 
 Tag
@@ -208,13 +208,6 @@ Way::implied_oneWay(const Tag &tag) {
         return;
     }
 
-    if (key == "highway"
-            && (value == "primary"
-                || value == "secondary"
-                || value == "tertiary")) {
-        m_oneWay = "NO";
-        return;
-    }
 }
 
 #if 0
@@ -332,7 +325,7 @@ Way::members_str() const {
     std::string node_list("");
     for (const auto &node_id : m_node_ids) {
         node_list += boost::lexical_cast<std::string>(node_id) + "=>\"type=>nd\",";
-    } 
+    }
     node_list[node_list.size() -1] = ' ';
 
     return node_list;
@@ -363,4 +356,3 @@ std::ostream& operator<<(std::ostream &os, const Way &way) {
 
 
 }  // namespace osm2pgr
-
diff --git a/src/osm_elements/osm2pgrouting.cpp b/src/osm_elements/osm2pgrouting.cpp
index 4b9218f..80b1db7 100644
--- a/src/osm_elements/osm2pgrouting.cpp
+++ b/src/osm_elements/osm2pgrouting.cpp
@@ -98,7 +98,7 @@ int main(int argc, char* argv[]) {
         }
 
         if (vm.count("version")) {
-            std::cout << "This is osm2pgrouting Version 2.3.1\n";
+            std::cout << "This is osm2pgrouting Version 2.3.3\n";
             return 0;
         }
 
@@ -173,13 +173,10 @@ int main(int argc, char* argv[]) {
         if (clean) {
             std::cout << "\nDropping tables..." << endl;
             dbConnection.dropTables();
-            std::cout << "\nCreating tables..." << endl;
-            dbConnection.createTables();
         }
-#if 0
         std::cout << "\nCreating tables..." << endl;
         dbConnection.createTables();
-#endif
+
         /* 
          * End: preparing the databasse
          */
diff --git a/src/osm_elements/osm_tag.cpp b/src/osm_elements/osm_tag.cpp
index 503ed64..6f122ec 100644
--- a/src/osm_elements/osm_tag.cpp
+++ b/src/osm_elements/osm_tag.cpp
@@ -31,6 +31,8 @@ Tag::Tag(const char **atts) {
         std::string name = *attribut++;
         std::string value = *attribut++;
         if (name  == "k") {
+            std::transform(value.begin(), value.end(), value.begin(), [](char ch) {
+                    return ch == ' ' ? '_' : ch;});
             m_key = value;
         } else if (name == "v") {
             m_value = value;
diff --git a/src/parser/OSMDocumentParserCallback.cpp b/src/parser/OSMDocumentParserCallback.cpp
index 53f54ae..2f3f13d 100644
--- a/src/parser/OSMDocumentParserCallback.cpp
+++ b/src/parser/OSMDocumentParserCallback.cpp
@@ -79,6 +79,11 @@ OSMDocumentParserCallback::StartElement(
         const char *name,
         const char** atts) {
     show_progress();
+
+    if (strcmp(name, "osm") == 0) {
+        m_section = 1;
+    }
+
     if ((m_section == 1 && (strcmp(name, "way") == 0))
             || (m_section == 2 && (strcmp(name, "relation") == 0))) {
         ++m_section;
@@ -151,8 +156,10 @@ OSMDocumentParserCallback::StartElement(
 void OSMDocumentParserCallback::EndElement(const char* name) {
     if (strcmp(name, "osm") == 0) {
         m_rDocument.endOfFile();
+        show_progress();
         return;
     }
+
     if (strcmp(name, "node") == 0) {
         m_rDocument.AddNode(*last_node);
         delete last_node;
@@ -172,8 +179,8 @@ void OSMDocumentParserCallback::EndElement(const char* name) {
         }
         delete last_way;
         return;
-
     }
+
     if (strcmp(name, "relation") == 0) {
         if (m_rDocument.config_has_tag(last_relation->tag_config())) {
             for (auto it = last_relation->way_refs().begin();  it != last_relation->way_refs().end(); ++it) {
@@ -194,9 +201,10 @@ void OSMDocumentParserCallback::EndElement(const char* name) {
             }
             m_rDocument.AddRelation(*last_relation);
         }
+        // TODO add all other relations
         delete last_relation;
-
-    }
+        return;
+    } 
 }
 
 }  // end namespace osm2pgr
diff --git a/tools/data/getdata.sh b/tools/data/getdata.sh
index c0659de..3351417 100644
--- a/tools/data/getdata.sh
+++ b/tools/data/getdata.sh
@@ -1,3 +1,23 @@
+#!sh
+
+exit(0);
+
+# https://github.com/GeographicaGS/osm-itinera/blob/master/itinera/const.py#L43
+BBOX="1.97180,41.26684,2.26478,41.55818"
+wget --progress=dot:mega -O "bcn.osm" "http://www.overpass-api.de/api/xapi?*[bbox=${BBOX}][@meta]"
+
+BBOX="13.15,47.24,13.52,47.45"
+wget --progress=dot:mega -O "restrictions.osm" "http://www.overpass-api.de/api/xapi?*[bbox=${BBOX}][@meta]"
+
+#query to get germany restrictions
+#(53.5,11.0,54.5,11.5)
+wget --progress=dot:mega -O "germany_restrictions.osm" "http://overpass-api.de/api/interpreter?data=(relation(53.5,11.0,54.5,11.5)[\"type\"~\"^restriction\"];);(._;>;);out;"
+
+#query to get world restrictions
+#times out does not work well
+wget --progress=dot:mega -O "world_restrictions.osm" "http://overpass-api.de/api/interpreter?data=(relation[\"type\"~\"^restriction\"];);(._;>;);out;"
+
+
 BBOX="-122.8,45.4,-122.5,45.6"
 wget --progress=dot:mega -O "sampledata.osm" "http://www.overpass-api.de/api/xapi?*[bbox=${BBOX}][@meta]"
 BBOX="-122.65,45.5, -122.5,45.6"
@@ -14,3 +34,19 @@ wget --progress=dot:mega -O "small.osm" "http://www.overpass-api.de/api/xapi?*[b
 
 BBOX="4.2878,50.8139,4.5023,50.8926"
 wget --progress=dot:mega -O "brussels.osm" "http://www.overpass-api.de/api/xapi?*[bbox=${BBOX}][@meta]"
+
+
+<osm-script>
+    <union>
+        <query type="relation">
+            <bbox-query e="13.52" n="47.45" s="47.34" w="13.15"/>
+            <has-kv k="type" v="restriction"/>
+        </query>
+
+    </union>
+    <union>
+        <item/>
+        <recurse type="down"/>
+    </union>
+    <print/>
+</osm-script>
diff --git a/CMakeLists.txt b/tools/osmium/CMakeLists.txt
similarity index 56%
copy from CMakeLists.txt
copy to tools/osmium/CMakeLists.txt
index de75fb8..6f7c914 100644
--- a/CMakeLists.txt
+++ b/tools/osmium/CMakeLists.txt
@@ -1,13 +1,31 @@
-PROJECT(osm2pgrouting)
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(getrestirction)
+CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
 
-set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
-set (SHARE_DIR "/usr/share/osm2pgrouting")
+if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} )
+    message(FATAL_ERROR "In-source builds not allowed.
+    Please make a new directory (called a build directory) and run CMake from there.
+    You may need to remove CMakeCache.txt." )
+endif()
+
+LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+SET(SHARE_DIR "/usr/share/getrestrictions")
 
 FIND_PACKAGE(PostgreSQL REQUIRED)
 find_package(LibPQXX REQUIRED)
 FIND_PACKAGE(EXPAT REQUIRED)
 
+
+find_package(Osmium REQUIRED COMPONENTS io pbf xml)
+if(NOT OSMIUM_FOUND)
+    message(WARNING "Libosmium not found!\n")
+endif()
+include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
+
+
+
+
+
+
 FIND_PACKAGE(Boost)
 if(Boost_INCLUDE_DIRS)
     message(STATUS "Boost headers were found here: ${Boost_INCLUDE_DIRS}")
@@ -17,10 +35,10 @@ endif(Boost_INCLUDE_DIRS)
 
 FIND_PACKAGE(Boost COMPONENTS program_options REQUIRED)
 
-FILE(GLOB osm2pgrouting_lib_SOURCES "${CMAKE_SOURCE_DIR}/src/*/*.cpp")
+FILE(GLOB SRC "${CMAKE_SOURCE_DIR}/src/*.cpp"  "${CMAKE_SOURCE_DIR}/src/*/*.cpp")
 
 set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FILE_OFFSET_BITS=64 -std=c++0x")
-set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wconversion -pedantic -Wextra  -frounding-math -Wno-deprecated -fmax-errors=10")
+set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -g -Wconversion -pedantic -Wextra  -frounding-math -Wno-deprecated -fmax-errors=10")
 
 
 set (OSM2PGROUTING_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/include")
@@ -40,32 +58,17 @@ INCLUDE_DIRECTORIES(src
     ${OSM2PGROUTING_INCLUDE_DIRS}
     )
 
-ADD_EXECUTABLE(osm2pgrouting ${osm2pgrouting_lib_SOURCES})
+ADD_EXECUTABLE(getrestrictions ${SRC})
 
-TARGET_LINK_LIBRARIES(osm2pgrouting
+TARGET_LINK_LIBRARIES(getrestrictions
     ${LIBPQXX_LIBRARIES}
     ${POSTGRESQL_LIBRARIES}
     ${EXPAT_LIBRARIES}
     ${Boost_LIBRARIES}
+    ${OSMIUM_LIBRARIES}
     )
 
-INSTALL(TARGETS osm2pgrouting
+INSTALL(TARGETS getrestrictions
     RUNTIME DESTINATION "/usr/bin"
     )
 
-if(WIN32)
-    target_link_libraries(osm2pgrouting wsock32 ws2_32)
-endif()
-
-INSTALL(FILES
-    "${CMAKE_SOURCE_DIR}/COPYING"
-    "${CMAKE_SOURCE_DIR}/Readme.md"
-    "${CMAKE_SOURCE_DIR}/mapconfig.xml"
-    "${CMAKE_SOURCE_DIR}/mapconfig_for_cars.xml"
-    "${CMAKE_SOURCE_DIR}/mapconfig_for_bicycles.xml"
-    "${CMAKE_SOURCE_DIR}/mapconfig_for_pedestrian.xml"
-    DESTINATION "${SHARE_DIR}")
-
-
-#INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )
-#TARGET_LINK_LIBRARIES( osm2pgrouting ${Boost_LIBRARIES} )
diff --git a/tools/osmium/README.md b/tools/osmium/README.md
new file mode 100644
index 0000000..c0536a6
--- /dev/null
+++ b/tools/osmium/README.md
@@ -0,0 +1,13 @@
+# Libosmium
+
+Instructions to install Libosmium library on Ubuntu:
+
+### 16.04 (Xenial)
+
+You need to install libosmium2-dev package:
+
+```
+$ apt update && apt install -y libosmium2-dev
+```
+
+Do not install libosmium-dev package. This is an old version of Libosmium and you can not use with osm2pgrouting.
diff --git a/tools/osmium/cmake/FindLibPQXX.cmake b/tools/osmium/cmake/FindLibPQXX.cmake
new file mode 100644
index 0000000..eec3360
--- /dev/null
+++ b/tools/osmium/cmake/FindLibPQXX.cmake
@@ -0,0 +1,43 @@
+# - Find libpqxx
+#   Find the libpqxx includes and client library
+# This module defines
+#  PQXX_INCLUDE_DIRS
+#  PQXX_LIBRARIES
+#  PQXX_FOUND
+
+include (FindPackageHandleStandardArgs)
+
+#
+# Look for an installation.
+#
+find_path(LIBPQXX_INCLUDE_DIR NAMES /include/pqxx/connection.hxx PATH_SUFFIXES ${SUFFIX_FOR_INCLUDE_PATH} PATHS
+
+    # Look in other places.
+    ${LIBPQXX_DIR_SEARCH}
+
+    # Help the user find it if we cannot.
+    DOC "The ${LIBPQXX_INCLUDE_DIR_MESSAGE}"
+    )
+
+# Now try to get the include and library path.
+if(LIBPQXX_INCLUDE_DIR)
+
+    if(EXISTS "${LIBPQXX_INCLUDE_DIR}")
+        set(LIBPQXX_INCLUDE_DIRS
+            ${LIBPQXX_INCLUDE_DIR}/include
+            )
+    endif()
+endif()
+
+find_library (LIBPQXX_LIBRARIES
+    NAMES
+    pqxx
+    )
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS("PQXX"
+    "libpqxx couldn't be found"
+    LIBPQXX_LIBRARIES
+    LIBPQXX_INCLUDE_DIRS
+    )
+
+mark_as_advanced (PQXX_INCLUDE_DIR PQXX_LIBRARY)
diff --git a/tools/osmium/cmake/FindOsmium.cmake b/tools/osmium/cmake/FindOsmium.cmake
new file mode 100644
index 0000000..8738654
--- /dev/null
+++ b/tools/osmium/cmake/FindOsmium.cmake
@@ -0,0 +1,369 @@
+#----------------------------------------------------------------------
+#
+#  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 [version] REQUIRED COMPONENTS <XXX>)
+#      include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
+#
+#    The version number is optional. If it is not set, any version of
+#    libosmium will do.
+#
+#    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.
+#
+#----------------------------------------------------------------------
+
+# This is the list of directories where we look for osmium and protozero
+# includes.
+set(_osmium_include_path
+        ../libosmium
+        ~/Library/Frameworks
+        /Library/Frameworks
+        /opt/local # DarwinPorts
+        /opt
+)
+
+# Look for the header file.
+find_path(OSMIUM_INCLUDE_DIR osmium/osm.hpp
+    PATH_SUFFIXES include
+    PATHS ${_osmium_include_path}
+)
+
+# Check libosmium version number
+if(Osmium_FIND_VERSION)
+    file(STRINGS "${OSMIUM_INCLUDE_DIR}/osmium/version.hpp" _libosmium_version_define REGEX "#define LIBOSMIUM_VERSION_STRING")
+    if("${_libosmium_version_define}" MATCHES "#define LIBOSMIUM_VERSION_STRING \"([0-9.]+)\"")
+        set(_libosmium_version "${CMAKE_MATCH_1}")
+    else()
+        set(_libosmium_version "unknown")
+    endif()
+endif()
+
+set(OSMIUM_INCLUDE_DIRS "${OSMIUM_INCLUDE_DIR}")
+
+#----------------------------------------------------------------------
+#
+#  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(ZLIB)
+    find_package(Threads)
+
+    message(STATUS "Looking for protozero")
+    find_path(PROTOZERO_INCLUDE_DIR protozero/version.hpp
+        PATH_SUFFIXES include
+        PATHS ${_osmium_include_path}
+              ${OSMIUM_INCLUDE_DIR}
+    )
+    if(PROTOZERO_INCLUDE_DIR)
+        message(STATUS "Looking for protozero - found")
+    else()
+        message(STATUS "Looking for protozero - not found")
+    endif()
+
+    list(APPEND OSMIUM_EXTRA_FIND_VARS ZLIB_FOUND Threads_FOUND PROTOZERO_INCLUDE_DIR)
+    if(ZLIB_FOUND AND Threads_FOUND AND PROTOZERO_INCLUDE_DIR)
+        list(APPEND OSMIUM_PBF_LIBRARIES
+            ${ZLIB_LIBRARIES}
+            ${CMAKE_THREAD_LIBS_INIT}
+        )
+        if(WIN32)
+            # This is needed for the ntohl() function
+            list(APPEND OSMIUM_PBF_LIBRARIES ws2_32)
+        endif()
+        list(APPEND OSMIUM_INCLUDE_DIRS
+            ${ZLIB_INCLUDE_DIR}
+            ${PROTOZERO_INCLUDE_DIR}
+        )
+    else()
+        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)
+
+    list(APPEND OSMIUM_EXTRA_FIND_VARS EXPAT_FOUND BZIP2_FOUND ZLIB_FOUND Threads_FOUND)
+    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()
+        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)
+
+    list(APPEND OSMIUM_EXTRA_FIND_VARS GEOS_INCLUDE_DIR GEOS_LIBRARY)
+    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()
+        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)
+
+    list(APPEND OSMIUM_EXTRA_FIND_VARS GDAL_FOUND)
+    if(GDAL_FOUND)
+        list(APPEND OSMIUM_LIBRARIES ${GDAL_LIBRARIES})
+        list(APPEND OSMIUM_INCLUDE_DIRS ${GDAL_INCLUDE_DIRS})
+    else()
+        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)
+
+    list(APPEND OSMIUM_EXTRA_FIND_VARS PROJ_INCLUDE_DIR PROJ_LIBRARY)
+    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()
+        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)
+
+    list(APPEND OSMIUM_EXTRA_FIND_VARS SPARSEHASH_INCLUDE_DIR)
+    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++.
+        if(NOT CMAKE_VERSION VERSION_LESS 3.0)
+           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)
+        else()
+           set(SPARSETABLE_SIZE_TYPE ${CMAKE_SIZEOF_VOID_P})
+        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()
+        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_EXTRA_FIND_VARS)
+    list(REMOVE_DUPLICATES OSMIUM_EXTRA_FIND_VARS)
+endif()
+# Handle the QUIETLY and REQUIRED arguments and the optional version check
+# 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 ${OSMIUM_EXTRA_FIND_VARS}
+                                  VERSION_VAR _libosmium_version)
+unset(OSMIUM_EXTRA_FIND_VARS)
+
+#----------------------------------------------------------------------
+#
+#  A function for setting the -pthread option in compilers/linkers
+#
+#----------------------------------------------------------------------
+function(set_pthread_on_target _target)
+    if(NOT MSVC)
+        set_target_properties(${_target} PROPERTIES COMPILE_FLAGS "-pthread")
+        if(NOT APPLE)
+            set_target_properties(${_target} PROPERTIES LINK_FLAGS "-pthread")
+        endif()
+    endif()
+endfunction()
+
+#----------------------------------------------------------------------
+#
+#  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)
+
+    # Disable warning C4503: "decorated name length exceeded, name was truncated"
+    # there are more than 150 of generated names in libosmium longer than 4096 symbols supported in MSVC
+    add_definitions(-wd4503)
+
+    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" 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/tools/osmium/cmake/FindPostgreSQL.cmake b/tools/osmium/cmake/FindPostgreSQL.cmake
new file mode 100644
index 0000000..a163233
--- /dev/null
+++ b/tools/osmium/cmake/FindPostgreSQL.cmake
@@ -0,0 +1,74 @@
+# - Find PostgreSQL
+# Find the PostgreSQL includes and client library
+# This module defines
+#  POSTGRESQL_INCLUDE_DIR, where to find POSTGRESQL.h
+#  POSTGRESQL_LIBRARIES, the libraries needed to use POSTGRESQL.
+#  POSTGRESQL_FOUND, If false, do not try to use PostgreSQL.
+
+# Copyright (c) 2006, Jaroslaw Staniek, <js at iidea.pl>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+if(POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
+    set(POSTGRESQL_FOUND TRUE)
+
+else(POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
+
+    find_program(POSTGRESQL_PG_CONFIG NAMES pg_config
+        PATHS
+        /usr/lib/postgresql/*/bin/
+        )
+    message(STATUS "POSTGRESQL_PG_CONFIG is " ${POSTGRESQL_PG_CONFIG})
+
+    if(POSTGRESQL_PG_CONFIG)
+        execute_process(
+            COMMAND ${POSTGRESQL_PG_CONFIG} --includedir
+            OUTPUT_STRIP_TRAILING_WHITESPACE
+            OUTPUT_VARIABLE T_POSTGRESQL_INCLUDE_DIR)
+    endif(POSTGRESQL_PG_CONFIG)
+
+    find_path(POSTGRESQL_INCLUDE_DIR libpq-fe.h
+        ${T_POSTGRESQL_INCLUDE_DIR}
+        /usr/include
+        /usr/include/pgsql
+        /usr/local/include/pgsql
+        /usr/include/postgresql
+        /usr/include/postgresql/*
+        /usr/local/include/postgresql
+        /usr/local/include/postgresql/*
+        $ENV{ProgramFiles}/PostgreSQL/*/include
+        $ENV{SystemDrive}/PostgreSQL/*/include
+        )
+
+    if(POSTGRESQL_PG_CONFIG)
+        execute_process(
+            COMMAND ${POSTGRESQL_PG_CONFIG} --libdir
+            OUTPUT_STRIP_TRAILING_WHITESPACE
+            OUTPUT_VARIABLE T_POSTGRESQL_LIB_DIR)
+    endif(POSTGRESQL_PG_CONFIG)
+
+    find_library(POSTGRESQL_LIBRARIES NAMES pq libpq
+        ${T_POSTGRESQL_LIB_DIR}
+        PATHS
+        /usr/lib
+        /usr/local/lib
+        /usr/lib/postgresql
+        $ENV{ProgramFiles}/PostgreSQL/*/lib
+        $ENV{SystemDrive}/PostgreSQL/*/lib
+        )
+
+    if(POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
+        set(POSTGRESQL_FOUND TRUE)
+        message(STATUS "POSTGRESQL_INCLUDE_DIR: ${POSTGRESQL_INCLUDE_DIR}")
+        message(STATUS "POSTGRESQL_LIBRARIES: ${POSTGRESQL_LIBRARIES}")
+        include_directories(${POSTGRESQL_INCLUDE_DIR})
+    else(POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
+        set(POSTGRESQL_FOUND FALSE)
+        message(STATUS "PostgreSQL not found.")
+    endif(POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
+
+    mark_as_advanced(POSTGRESQL_INCLUDE_DIR POSTGRESQL_LIBRARIES)
+
+endif(POSTGRESQL_INCLUDE_DIR AND POSTGRESQL_LIBRARIES)
diff --git a/tools/osmium/include/collectors/turn_restrictions.h b/tools/osmium/include/collectors/turn_restrictions.h
new file mode 100644
index 0000000..46c80fd
--- /dev/null
+++ b/tools/osmium/include/collectors/turn_restrictions.h
@@ -0,0 +1,91 @@
+/*PGR-GNU*****************************************************************
+File: turn_restrictions.h
+
+Copyright (c) 2017 pgRouting developers
+
+File developer: Celia Virginia Vergara Castillo (2017)
+
+
+------
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+********************************************************************PGR-GNU*/
+
+/*! @file */
+
+#ifndef TOOLS_OSMIUM_INCLUDE_COLLECTORS_TURN_RESTRICTIONS_H_
+#define TOOLS_OSMIUM_INCLUDE_COLLECTORS_TURN_RESTRICTIONS_H_
+#pragma once
+
+#include <string>
+#include <iostream>  // for std::cout, std::cerr
+
+
+// For the NodeLocationForWays handler
+#include <osmium/handler/node_locations_for_ways.hpp>
+#include <osmium/relations/collector.hpp>
+#include <osmium/index/map/sparse_mem_array.hpp>
+
+
+
+class MyRelCollector :
+    public osmium::relations::Collector<MyRelCollector, true, true, true> {
+ public:
+    MyRelCollector();
+    explicit MyRelCollector(std::ostream &file);
+
+    /**
+     * Interested in all relations tagged with type=restriction
+     *
+     * OSM WIKI about restrictions
+     * http://wiki.openstreetmap.org/wiki/Relation:restriction
+     *
+     * Overwritten from the base class.
+     */
+    bool keep_relation(const osmium::Relation& relation) const;
+
+    /**
+     * Overwritten from the base class.
+     */
+    bool keep_member(
+            const osmium::relations::RelationMeta&,
+            const osmium::RelationMember& member) const;
+
+    /*
+     * (2654080,'no_right_turn',30513235,30513221,336812979,'n','version=>1,timestamp=>2012-12-22T17:01:50Z,changeset=>14368535,uid=>381316,user=>Schermy'::hstore,'except=>hgv,restriction=>no_right_turn,type=>restriction'::hstore)
+     */
+    std::string attributes_str(
+            const osmium::Relation& relation) const;
+
+
+    std::string tags_str(
+            const osmium::Relation& relation) const;
+
+    /** A Restriction:
+     *
+     * from: is of type way
+     * to: is of type way
+     * via: can be of type way or node
+     * can not have a member relation
+     *
+     * Overwritten from the base class.
+     */
+    void complete_relation(osmium::relations::RelationMeta& relation_meta);
+
+    void flush();
+
+ private:
+    std::ostream &m_file;
+};
+
+
+#endif  // TOOLS_OSMIUM_INCLUDE_COLLECTORS_TURN_RESTRICTIONS_H_
diff --git a/tools/osmium/include/quotes_handling.cpp b/tools/osmium/include/quotes_handling.cpp
new file mode 100644
index 0000000..637a461
--- /dev/null
+++ b/tools/osmium/include/quotes_handling.cpp
@@ -0,0 +1,310 @@
+
+#include <fstream>
+#include <iostream> // for std::cout, std::cerr
+#if 0
+#include <osmium/osm/types.hpp>
+#include <osmium/osm/location.hpp>
+#include <osmium/osm/segment.hpp>
+#include <osmium/osm/undirected_segment.hpp>
+#include <osmium/osm/box.hpp>
+#include <osmium/osm/object.hpp>
+#include <osmium/builder/builder.hpp>
+#include <osmium/builder/osm_object_builder.hpp>
+#include <osmium/io/any_compression.hpp>
+#endif
+#include <osmium/index/map/sparse_mem_array.hpp>
+#include <osmium/relations/collector.hpp>
+
+#if 0
+#include <cstdlib>  // for std::exit
+#include <getopt.h> // for getopt_long
+#endif
+
+#if 0
+// For assembling multipolygons
+#include <osmium/area/assembler.hpp>
+#include <osmium/area/multipolygon_collector.hpp>
+#endif
+
+// For the DynamicHandler class
+#include <osmium/dynamic_handler.hpp>
+
+#if 0
+// For the WKT factory
+#include <osmium/geom/wkt.hpp>
+#endif
+
+#if 0
+// For the Dump handler
+#include <osmium/handler/dump.hpp>
+#endif
+
+#if 1
+// For the NodeLocationForWays handler
+#include <osmium/handler/node_locations_for_ways.hpp>
+#endif
+
+// Allow any format of input files (XML, PBF, ...)
+#include <osmium/io/any_input.hpp>
+
+#if 0
+// For osmium::apply()
+#include <osmium/visitor.hpp>
+#endif
+
+#if 0
+// For the location index. There are different types of indexes available.
+// This will work for small and medium sized input files.
+#include <osmium/index/map/sparse_mem_array.hpp>
+#endif
+
+
+using index_type = osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location>;
+using location_handler_type = osmium::handler::NodeLocationsForWays<index_type>;
+
+std::string
+add_quotes(const std::string str, bool force) {
+    std::string result("");
+
+    for (auto c : str) {
+        if ( c == '"' ) {
+            /*
+             * To avoid problems with json & hstore
+             * all quotes are converted to single quotes
+             */
+            result += "\'\'";
+            continue;
+        } else if ( c == '\\' ) {
+            result += '\\';
+        } else if (c == '\'') {
+            result += '\'';
+        } else if (c == '\n') {
+            result += "\\n";
+            continue;
+        } else if (c == '\r') {
+            result += "\\r";
+            continue;
+        } else if (c == '\t') {
+            result += "\\t";
+            continue;
+        }
+        result += c;
+    }
+    if (!force) {
+        for (auto c : result) {
+            if  (c == ' ' || c == ',' || c == '=' || c == '>' || c == ':') {
+                return std::string("\"") + result + "\"";
+            }
+        }
+        return result;
+    }
+    return std::string("\"") + result + "\"";
+}
+
+
+class MyRelCollector : public osmium::relations::Collector<MyRelCollector, true, true, true> {
+
+    public:
+
+    MyRelCollector() :
+        m_file(std::cout) {
+    }
+
+    MyRelCollector(std::ostream &file) :
+        m_file(file) {
+    }
+
+
+    /**
+     * Interested in all relations tagged with type=restriction
+     *
+     * OSM WIKI about restrictions
+     * http://wiki.openstreetmap.org/wiki/Relation:restriction
+     *
+     * Overwritten from the base class.
+     */
+    bool keep_relation(const osmium::Relation& relation) const {
+        const char* type = relation.tags().get_value_by_key("type");
+        /*
+         * known transportation modes
+         * TODO save in a configuration file
+         */
+        std::vector<std::string> transportation_mode{"hgv","caravan","motorcar","bus","agricultural","bicycle","hazmat","psv","emergency"}; 
+
+        /*
+         *  ignore relations without "type" tag
+         */
+        if (!type) {
+            return false;
+        }
+
+        if ((!std::strcmp(type, "restriction"))) {
+            return true;
+        }
+
+        for (const auto& tm : transportation_mode) {
+            if ((std::string("restriction:") + tm) == std::string(type)) return true;
+        }
+        return false;
+    }
+
+    /**
+     * Overwritten from the base class.
+     */
+    bool keep_member(
+            const osmium::relations::RelationMeta&,
+            const osmium::RelationMember& member) const {
+        /*
+         * Interested in members of type way & node.
+         */
+        return member.type() == osmium::item_type::way || 
+            member.type() == osmium::item_type::node;
+    }
+
+    /*
+     * (2654080,'no_right_turn',30513235,30513221,336812979,'n','version=>1,timestamp=>2012-12-22T17:01:50Z,changeset=>14368535,uid=>381316,user=>Schermy'::hstore,'except=>hgv,restriction=>no_right_turn,type=>restriction'::hstore)
+     */
+    std::string attributes_str(
+            const osmium::Relation& relation) const {
+        std::string user = std::string(relation.user());
+        user = add_quotes(user, true);
+        std::string str("");
+        str += "version=>" + std::to_string(relation.version()) + ",";
+        str += "timestamp=>" + relation.timestamp().to_iso() + ",";
+        str += "changeset=>" + std::to_string(relation.changeset()) + ",";
+        str += "uid=>" + std::to_string(relation.uid()) + ",";
+        str += "user=>" + user;
+        return str;
+    }
+
+
+    std::string tags_str(
+            const osmium::Relation& relation) const {
+        std::string str("");
+        for (const osmium::Tag& tag : relation.tags()) {
+            str += std::string(tag.key()) + "=>" +  tag.value() + ',';
+        }
+        str[str.size()-1] = ' ';
+        return str;
+    }
+
+    /** A Restriction:
+     *
+     * from: is of type way
+     * to: is of type way
+     * via: can be of type way or node
+     * can not have a member relation
+     *
+     * Overwritten from the base class.
+     */
+    void complete_relation(osmium::relations::RelationMeta& relation_meta) {
+        const osmium::Relation& relation = this->get_relation(relation_meta);
+
+        osmium::object_id_type from;
+        osmium::object_id_type to;
+        osmium::object_id_type via;
+        osmium::item_type via_type;
+
+        for (const auto& member : relation.members()) {
+            if  (!std::strcmp(member.role(),"via")) {
+                via = member.ref();
+                via_type = member.type();
+            } else if  (!std::strcmp(member.role(),"from")) {
+                from = member.ref();
+            } else if  (!std::strcmp(member.role(),"to")) {
+                to = member.ref();
+            } else {
+                std::cout << "Found an illegal member relation in restriction\n";
+                assert(false);
+            }
+        }
+        m_file
+            << relation.id() << "\t"
+            << "'" << relation.get_value_by_key("restriction") << "'\t"
+            << from << "\t"
+            << to << "\t"
+            << via << "\t"
+            <<  via_type << "\t"
+            << attributes_str(relation) << "\t"
+            << tags_str(relation)
+            << "\n";
+    }
+
+    void flush() {
+        this->callback();
+    }
+  private:
+
+    std::ostream &m_file;
+};
+
+
+
+
+main() {
+    /*
+     * The output file
+     */
+    std::ofstream of("restrictions_output.sql");
+
+    /*
+     * Reading the create table query
+     */
+    std::ifstream f("../restrictions.sql");
+    std::stringstream buffer;
+
+    of  << f.rdbuf();
+    std::string str = buffer.str();
+    std::cout << str << "\n";
+    f.close();
+
+    osmium::handler::DynamicHandler handler;
+    osmium::relations::RelationMeta relation_meta;
+    MyRelCollector collector(of);
+    std::cerr << "Pass 1...\n";
+    osmium::io::Reader reader1{"../../../tools/data/restrictions.osm", osmium::osm_entity_bits::relation};
+    collector.read_relations(reader1);
+    reader1.close();
+    std::cerr << "Pass 1 done\n";
+
+
+    // Output the amount of main memory used so far. All multipolygon relations
+    // are in memory now.
+    std::cerr << "Memory:\n";
+    collector.used_memory();
+
+    // The index storing all node locations.
+    index_type index;
+
+    // The handler that stores all node locations in the index and adds them
+    // to the ways.
+    location_handler_type location_handler{index};
+
+    // If a location is not available in the index, we ignore it. It might
+    // not be needed (if it is not part of a multipolygon relation), so why
+    // create an error?
+    location_handler.ignore_errors();
+
+    // On the second pass we read all objects and run them first through the
+    // node location handler and then the multipolygon collector. The collector
+    // will put the areas it has created into the "buffer" which are then
+    // fed through our "handler".
+    std::cerr << "Pass 2...\n";
+    osmium::io::Reader reader2{"../../../tools/data/restrictions.osm"};
+    osmium::apply(reader2, location_handler, collector.handler([&handler](osmium::memory::Buffer&& buffer) {
+                osmium::apply(buffer, handler);
+                }));
+    reader2.close();
+    std::cout << "\\.";
+    std::cerr << "Pass 2 done\n";
+    std::ifstream l("../restrictions_end.sql");
+    of  << "\\.";
+    of  << l.rdbuf();
+    l.close();
+    of.close();
+
+    // Output the amount of main memory used so far. All complete multipolygon
+    // relations have been cleaned up.
+    std::cerr << "Memory:\n";
+    collector.used_memory();
+}
diff --git a/tools/osmium/include/utilities/quotes_handling.h b/tools/osmium/include/utilities/quotes_handling.h
new file mode 100644
index 0000000..3b56969
--- /dev/null
+++ b/tools/osmium/include/utilities/quotes_handling.h
@@ -0,0 +1,40 @@
+/*PGR-GNU*****************************************************************
+File: quotes_handling.h
+
+Copyright (c) 2017 pgRouting developers
+
+File developer: Celia Virginia Vergara Castillo (2017)
+
+
+------
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+********************************************************************PGR-GNU*/
+
+/*! @file */
+
+#ifndef TOOLS_OSMIUM_INCLUDE_UTILITIES_QUOTES_HANDLING_H_
+#define TOOLS_OSMIUM_INCLUDE_UTILITIES_QUOTES_HANDLING_H_
+
+#include <string>
+#include <sstream>
+
+std::string
+add_quotes(const std::string str, bool force = false);
+
+std::string
+pg_null(const std::ostringstream &original);
+
+std::string
+pg_null_array(const std::ostringstream &original);
+
+#endif  // TOOLS_OSMIUM_INCLUDE_UTILITIES_QUOTES_HANDLING_H_
diff --git a/tools/osmium/restrictions.sql b/tools/osmium/restrictions.sql
new file mode 100644
index 0000000..ca378ee
--- /dev/null
+++ b/tools/osmium/restrictions.sql
@@ -0,0 +1,53 @@
+
+BEGIN;
+--DROP TABLE if EXISTS foo.osm_restrictions;
+
+--
+-- osm2pgRouting osm_restrictions dump
+--
+
+SET statement_timeout = 0;
+SET lock_timeout = 0;
+SET client_encoding = 'UTF8';
+SET standard_conforming_strings = on;
+SET check_function_bodies = false;
+SET client_min_messages = warning;
+
+SET search_path = public, pg_catalog;
+
+SET default_tablespace = '';
+
+SET default_with_oids = false;
+
+--
+-- Name: osm_restrictions; Type: TABLE; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE SCHEMA IF NOT EXISTS foo;
+
+CREATE TABLE IF NOT EXISTS foo.osm_restrictions(
+    osm_id BIGINT PRIMARY KEY,
+    osm_from    BIGINT[],
+    osm_to      BIGINT[],
+    osm_via     BIGINT[],
+    via_type char,
+    osm_location_hint BIGINT,
+    attributes hstore,
+    tags hstore);
+
+-- On a created table the temporary table is not needed
+CREATE TEMP TABLE __osm_restrictions_tmp
+ON COMMIT DROP
+AS
+SELECT *
+FROM foo.osm_restrictions
+WITH NO DATA;
+
+
+-- On a created table Use the original table
+COPY __osm_restrictions_tmp (
+    osm_id,
+    osm_from, osm_to, osm_via,
+    via_type,
+    osm_location_hint,
+    attributes, tags) FROM STDIN;
diff --git a/tools/osmium/restrictions_end.sql b/tools/osmium/restrictions_end.sql
new file mode 100644
index 0000000..1a1ccb3
--- /dev/null
+++ b/tools/osmium/restrictions_end.sql
@@ -0,0 +1,27 @@
+
+
+-- On a created table the delete is not needed
+-- FROM pg >= 9.5 this delete is not needed
+DELETE FROM __osm_restrictions_tmp WHERE osm_id IN (SELECT osm_id FROM foo.osm_restrictions);
+
+INSERT INTO foo.osm_restrictions
+SELECT *
+FROM __osm_restrictions_tmp;
+-- FROM pg >= 9.5 this line is needed
+-- ON CONFLICT DO NOTHING
+
+-- With if the table had the primary key then it wont create it
+DO $$
+    BEGIN
+        BEGIN
+            ALTER TABLE ONLY foo.osm_restrictions
+            ADD CONSTRAINT foo.osm_restrictions_pkey PRIMARY KEY (osm_id);
+            EXCEPTION
+               WHEN OTHERS THEN
+                RAISE NOTICE 'Primary key "foo.osm_restrictions_pkey" EXISTS'
+                USING HINT = 'postgreSQL code #' ||  SQLSTATE || ': ' || SQLERRM;
+        END;
+    END
+$$;
+
+COMMIT;
diff --git a/tools/osmium/src/collectors/turn_restriccions.cpp b/tools/osmium/src/collectors/turn_restriccions.cpp
new file mode 100644
index 0000000..ce43a8f
--- /dev/null
+++ b/tools/osmium/src/collectors/turn_restriccions.cpp
@@ -0,0 +1,227 @@
+/*PGR-GNU*****************************************************************
+ * File: turn_restrictions.cpp
+ *
+ * Copyright(c) 2017 pgRouting developers
+ *
+ * File developer: Celia Virginia Vergara Castillo (2017)
+ *
+ *
+ * ------
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *  ********************************************************************PGR-GNU*/
+
+/*! @file */
+
+
+#include "collectors/turn_restrictions.h"
+
+#include <fstream>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include "utilities/quotes_handling.h"
+
+
+MyRelCollector::MyRelCollector() :
+    m_file(std::cout) {
+    }
+
+MyRelCollector::MyRelCollector(std::ostream &file) :
+    m_file(file) {
+    }
+
+/**
+ * Interested in all relations tagged with type=restriction
+ *
+ * OSM WIKI about restrictions
+ * http://wiki.openstreetmap.org/wiki/Relation:restriction
+ *
+ * Overwritten from the base class.
+ */
+bool MyRelCollector::keep_relation(const osmium::Relation& relation) const {
+    const char* type = relation.tags().get_value_by_key("type");
+    //std::cout <<  "my function name is: " << __FUNCTION__ << "\n";
+    /*
+     * known transportation modes
+     * TODO save in a configuration file
+     */
+    std::vector<std::string> transportation_mode{
+        "hgv", "caravan", "motorcar", "bus",
+            "agricultural", "bicycle", "hazmat", "psv", "emergency"};
+
+    /*
+     *  ignore relations without "type" tag
+     */
+    if (!type) {
+        return false;
+    }
+
+    if ((!std::strcmp(type, "restriction"))) {
+        return true;
+    }
+
+#if 0
+    for (const auto& tm : transportation_mode) {
+        if ((std::string("restriction:") + tm) == std::string(type)) {
+            return true;
+        }
+    }
+#endif
+    return false;
+}
+
+/**
+ * Overwritten from the base class.
+ */
+bool MyRelCollector::keep_member(
+        const osmium::relations::RelationMeta&,
+        const osmium::RelationMember &member) const {
+    //std::cout <<  "my function name is: " << __FUNCTION__ << "\n";
+#if 0
+    /*
+     * Interested in members of type way & node.
+     */
+    return member.type() == osmium::item_type::way ||
+        member.type() == osmium::item_type::node;
+#else
+    return true;
+#endif
+}
+
+/*
+ * (2654080,'no_right_turn',30513235,30513221,336812979,'n','version=>1,timestamp=>2012-12-22T17:01:50Z,changeset=>14368535,uid=>381316,user=>Schermy'::hstore,'except=>hgv,restriction=>no_right_turn,type=>restriction'::hstore)
+ */
+std::string MyRelCollector::attributes_str(
+        const osmium::Relation& relation) const {
+    //std::cout <<  "my function name is: " << __FUNCTION__ << "\n";
+    std::string user = add_quotes(std::string(relation.user()));
+    std::string str("");
+    str += "version=>" + std::to_string(relation.version()) + ",";
+    str += "timestamp=>" + relation.timestamp().to_iso() + ",";
+    str += "changeset=>" + std::to_string(relation.changeset()) + ",";
+    str += "uid=>" + std::to_string(relation.uid()) + ",";
+    str += "user=>" + add_quotes(std::string(relation.user()));
+    return str;
+}
+
+
+std::string MyRelCollector::tags_str(
+        const osmium::Relation& relation) const {
+    std::string str("");
+    for (const osmium::Tag& tag : relation.tags()) {
+        str += std::string(tag.key()) + "=>" +  add_quotes(tag.value()) + ',';
+    }
+    str[str.size()-1] = ' ';
+    return str;
+}
+
+/** A Restriction:
+ *
+ * from: is of type way
+ * to: is of type way
+ * via: can be of type way or node
+ * can not have a member relation
+ *
+ * Overwritten from the base class.
+ */
+void MyRelCollector::complete_relation(
+        osmium::relations::RelationMeta& relation_meta) {
+    const osmium::Relation& relation = this->get_relation(relation_meta);
+    //std::cout <<  "my function name is: " << __FUNCTION__ << "\n";
+
+    /*
+     * http://wiki.openstreetmap.org/wiki/Relation:restriction#Members
+     *
+     * From:  A no_entry restriction can have more than 1 from member, all others have exactly 1 from.
+     * to:   A no_exit restriction can have more than 1 to member, all others have exactly 1 to.
+     * Via: One node
+     * Via: One or more ways
+     */
+     std::ostringstream from;
+     std::ostringstream to;
+     std::ostringstream via;
+     std::ostringstream location_hint;
+     osmium::item_type via_type;
+
+    for (const auto &member : relation.members()) {
+        if (!std::strcmp(member.role(), "via")) {
+            if (via.str().empty()) {
+                /*
+                 * Via: One or more ways with a via role
+                 * Catching only the first via_type (n, w)
+                 * - all the others (if any) must be the same
+                 *   - Not checking here
+                 *
+                 *
+                 * On the database:
+                 * - if via_type is n:
+                 *   - the array must be of size == 1
+                 *   - the array[i] contains node ID
+                 * - if via_type is w:
+                 *   - the array can be of size >= 1
+                 *   - the array[i] contains ways ID
+                 */
+                via_type = member.type();
+            } else {
+                via << ",";
+            }
+
+            via << member.ref();
+
+        } else if (!std::strcmp(member.role(), "from")) {
+            if (!from.str().empty()) {
+                from << ",";
+            }
+            from << member.ref();
+        } else if (!std::strcmp(member.role(), "to")) {
+            if (!to.str().empty()) {
+                to << ",";
+            }
+            to << member.ref();
+        } else if (!std::strcmp(member.role(), "location_hint")) {
+            location_hint << member.ref();
+        } else {
+            std::cerr
+                << "Found currently unsuported member role: '"
+                << member.role()
+                << "' on restriction: " << relation.id() << "\n";
+        }
+    }
+#if 0
+    std::cout 
+        << relation.id() << "\t"
+        << pg_null_array(from) << "\t"
+        << pg_null_array(to) << "\t"
+        << pg_null_array(via) << "\t"
+        << via_type << "\t"
+        << pg_null(location_hint) << "\t"
+        << attributes_str(relation) << "\t"
+        << tags_str(relation)
+        << "\n";
+#endif
+    m_file
+        << relation.id() << "\t"
+        << pg_null_array(from) << "\t"
+        << pg_null_array(to) << "\t"
+        << pg_null_array(via) << "\t"
+        << via_type << "\t"
+        << pg_null(location_hint) << "\t"
+        << attributes_str(relation) << "\t"
+        << tags_str(relation)
+        << "\n";
+}
+
+void MyRelCollector::flush() {
+    this->callback();
+}
diff --git a/tools/osmium/src/getrestrictions.cpp b/tools/osmium/src/getrestrictions.cpp
new file mode 100644
index 0000000..ea9dfdf
--- /dev/null
+++ b/tools/osmium/src/getrestrictions.cpp
@@ -0,0 +1,136 @@
+/*PGR-GNU*****************************************************************
+ * File: getrestrictions.cpp
+ *
+   Copyright (c) 2017 pgRouting developers
+ *
+ * File developer: Celia Virginia Vergara Castillo (2017)
+ *
+ *
+ * ------
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *  ********************************************************************PGR-GNU*/
+
+/*! @file */
+
+
+#include <fstream>
+#include <iostream> // for std::cout, std::cerr
+
+#include "utilities/quotes_handling.h"
+#include "collectors/turn_restrictions.h"
+
+// For the DynamicHandler class
+#include <osmium/dynamic_handler.hpp>
+
+
+// For the NodeLocationForWays handler
+#include <osmium/handler/node_locations_for_ways.hpp>
+
+// Allow any format of input files (XML, PBF, ...)
+#include <osmium/io/any_input.hpp>
+
+
+
+
+
+main(int argc, char *argv[]) {
+    using index_type = osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location>;
+    using location_handler_type = osmium::handler::NodeLocationsForWays<index_type>;
+
+    if (argc != 2) {
+        std::cerr << "file to process missing\n";
+        exit(1);
+    }
+    /*
+     *  the input file
+     */
+    std::string in_file_name = argv[1];
+    std::string out_file_name = 
+        std::string(in_file_name, 0, in_file_name.size()-4) + "_restrictions.sql";
+
+    std::cout << "processing: " << in_file_name << "\n";
+    std::cout << "results at: " << out_file_name << "\n";
+
+    /*
+     * The output file
+     */
+    std::ofstream of(out_file_name);
+
+    /*
+     * Reading the create table query
+     */
+    std::ifstream f("../restrictions.sql");
+    std::stringstream buffer;
+
+    /*
+     * output of the create tables
+     */
+    of << f.rdbuf();
+
+    f.close();
+
+    std::string str = buffer.str();
+    std::cout << str << "\n";
+
+    osmium::handler::DynamicHandler handler;
+    osmium::relations::RelationMeta relation_meta;
+
+    MyRelCollector collector(of);
+    std::cerr << "Pass 1...\n";
+    osmium::io::Reader reader1{in_file_name, osmium::osm_entity_bits::relation};
+    collector.read_relations(reader1);
+    reader1.close();
+    std::cerr << "Pass 1 done\n";
+
+
+    // Output the amount of main memory used so far. All multipolygon relations
+    // are in memory now.
+    std::cerr << "Memory:\n";
+    collector.used_memory();
+
+    // The index storing all node locations.
+    index_type index;
+
+    // The handler that stores all node locations in the index and adds them
+    // to the ways.
+    location_handler_type location_handler{index};
+
+    // If a location is not available in the index, we ignore it. It might
+    // not be needed (if it is not part of a multipolygon relation), so why
+    // create an error?
+    location_handler.ignore_errors();
+
+    // On the second pass we read all objects and run them first through the
+    // node location handler and then the multipolygon collector. The collector
+    // will put the areas it has created into the "buffer" which are then
+    // fed through our "handler".
+    std::cerr << "Pass 2...\n";
+    osmium::io::Reader reader2{in_file_name};
+    osmium::apply(reader2, location_handler, collector.handler([&handler](osmium::memory::Buffer&& buffer) {
+                osmium::apply(buffer, handler);
+                }));
+    of  << "\\.";
+    std::cerr << "Pass 2 done\n";
+
+    std::ifstream l("../restrictions_end.sql");
+    of  << l.rdbuf();
+    l.close();
+
+    of.close();
+
+    reader2.close();
+    // Output the amount of main memory used so far. All complete multipolygon
+    // relations have been cleaned up.
+    std::cerr << "Memory:\n";
+    collector.used_memory();
+}
diff --git a/tools/osmium/src/utilities/quotes_handling.cpp b/tools/osmium/src/utilities/quotes_handling.cpp
new file mode 100644
index 0000000..2ebcc50
--- /dev/null
+++ b/tools/osmium/src/utilities/quotes_handling.cpp
@@ -0,0 +1,78 @@
+/*PGR-GNU*****************************************************************
+ * File: quotes_handling.cpp
+ *
+ * Copyright (c) 2017 pgRouting developers
+ *
+ * File developer: Celia Virginia Vergara Castillo (2017)
+ *
+ *
+ * ------
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *  ********************************************************************PGR-GNU*/
+
+/*! @file */
+
+
+#include "utilities/quotes_handling.h"
+#include <string>
+
+std::string
+add_quotes(const std::string str, bool force) {
+    std::string result("");
+
+    for (auto c : str) {
+        if ( c == '"' ) {
+            /*
+             * To avoid problems with json & hstore
+             * all quotes are converted to single quotes
+             */
+            result += "\'\'";
+            continue;
+        } else if ( c == '\\' ) {
+            result += '\\';
+        } else if (c == '\'') {
+            result += '\'';
+        } else if (c == '\n') {
+            result += "\\n";
+            continue;
+        } else if (c == '\r') {
+            result += "\\r";
+            continue;
+        } else if (c == '\t') {
+            result += "\\t";
+            continue;
+        }
+        result += c;
+    }
+    if (!force) {
+        for (auto c : result) {
+            if  (c == ' ' || c == ',' || c == '=' || c == '>' || c == ':') {
+                return std::string("\"") + result + "\"";
+            }
+        }
+        return result;
+    }
+    return std::string("\"") + result + "\"";
+}
+
+
+std::string
+pg_null(const std::ostringstream &original) {
+    return original.str().empty() ? "\\N" : original.str();
+};
+
+std::string
+pg_null_array(const std::ostringstream &original) {
+    return original.str().empty() ? "\\N" : "{" + original.str() + "}";
+};
+

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



More information about the Pkg-grass-devel mailing list