[osm2pgrouting] 02/08: New upstream version 2.3.0
Bas Couwenberg
sebastic at debian.org
Wed Oct 11 16:51:11 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 916b7c024802bc36370ff67d32adf98fbb5125ed
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Wed Oct 11 18:17:30 2017 +0200
New upstream version 2.3.0
---
.gitignore | 1 +
.travis.yml | 22 +-
AUTHORS.md | 1 +
CMakeLists.txt | 33 +-
NEWS | 9 +
Readme.md | 29 +-
ci/travis/install-libpqxx.sh | 26 +
ci/travis/osm2pgrouting_build.sh | 8 +-
cmake/FindLibPQXX.cmake | 43 +
include/configuration/configuration.h | 99 +++
src/Type.h => include/configuration/tag_key.h | 50 +-
src/Class.h => include/configuration/tag_value.h | 34 +-
include/database/Export2DB.h | 153 ++++
include/database/table_management.h | 161 ++++
{src => include/osm_elements}/Node.h | 11 +-
include/osm_elements/OSMDocument.h | 159 ++++
{src => include/osm_elements}/Relation.h | 3 +
{src => include/osm_elements}/Way.h | 17 +-
{src => include/osm_elements}/osm_element.h | 15 +-
{src => include/osm_elements}/osm_tag.h | 0
.../parser}/ConfigurationParserCallback.h | 4 +-
.../parser}/OSMDocumentParserCallback.h | 3 +-
{src => include/parser}/XMLParser.h | 0
include/utilities/handle_pgpass.h | 29 +
{src => include/utilities}/print_progress.h | 2 +-
{src => include/utilities}/prog_options.h | 0
include/utilities/utilities.h | 30 +
mapconfig.xml | 88 +-
mapconfig_for_bicycles.xml | 116 +--
mapconfig_for_cars.xml | 38 +-
mapconfig_for_pedestrian.xml | 23 +
src/Class.cpp | 57 --
src/Configuration.h | 76 --
src/Export2DB.cpp | 944 ---------------------
src/Export2DB.h | 160 ----
src/OSMDocument.cpp | 136 ---
src/OSMDocument.h | 100 ---
src/configuration/configuration.cpp | 93 ++
src/{Type.cpp => configuration/tag_key.cpp} | 72 +-
.../tag_value.cpp} | 49 +-
src/database/Export2DB.cpp | 700 +++++++++++++++
src/database/configuration_config.cpp | 81 ++
src/database/osm_nodes_config.cpp | 82 ++
src/database/osm_relations_config.cpp | 83 ++
src/database/osm_ways_config.cpp | 88 ++
src/database/pois_config.cpp | 89 ++
src/database/table_management.cpp | 444 ++++++++++
src/database/ways_config.cpp | 130 +++
src/database/ways_vertices_pgr_config.cpp | 79 ++
src/osm_element.cpp | 105 ---
src/{ => osm_elements}/Node.cpp | 23 +-
src/osm_elements/OSMDocument.cpp | 267 ++++++
src/{ => osm_elements}/Relation.cpp | 17 +-
src/{ => osm_elements}/Way.cpp | 64 +-
src/{ => osm_elements}/osm2pgrouting.cpp | 158 +++-
src/osm_elements/osm_element.cpp | 233 +++++
src/{ => osm_elements}/osm_tag.cpp | 2 +-
src/{ => parser}/ConfigurationParserCallback.cpp | 25 +-
src/{ => parser}/OSMDocumentParserCallback.cpp | 70 +-
src/{ => parser}/XMLParser.cpp | 3 +-
src/utilities/handle_pgpass.cpp | 94 ++
src/{ => utilities}/prog_options.cpp | 26 +-
src/utilities/utilities.cpp | 47 +
tools/data/getdata.sh | 2 +
tools/doxygen/Doxyfile | 12 +-
tools/doxygen/images/pgrouting-logo.png | Bin 0 -> 19294 bytes
66 files changed, 3851 insertions(+), 1967 deletions(-)
diff --git a/.gitignore b/.gitignore
index b749c06..001d9f8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ Sample/*
build
osm2pgrouting
tools/vagrant/packaging.sh
+fix_typos
*.o
*.out
*.osm
diff --git a/.travis.yml b/.travis.yml
index a64d480..c129de1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,42 +22,31 @@ compiler:
# email:
# on_failure: project at pgrouting.org
-env: POSTGRESQL_VERSION=9.6 PG_USER=postgres
+env: POSTGRESQL_VERSION=9.6 PG_USER=postgres DIST=precise
matrix:
include:
- - os: linux
- sudo: required
- dist: precise
- env: POSTGRESQL_VERSION=9.5 PG_USER=postgres
-
-
- - os: linux
- sudo: required
- dist: precise
- env: POSTGRESQL_VERSION=9.4 PG_USER=postgres
-
- os: linux
sudo: required
dist: trusty
group: edge
- env: POSTGRESQL_VERSION=9.6 PG_USER=postgres
+ 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
+ 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
+ env: POSTGRESQL_VERSION=9.4 PG_USER=postgres DIST=trusty
@@ -80,7 +69,8 @@ before_install:
- sudo sudo apt-get install -y libboost-program-options-dev
install:
- - sudo ./ci/travis/install-postgres.sh $POSTGRESQL_VERSION $PG_USER
+ #- sudo ./ci/travis/install-postgres.sh $POSTGRESQL_VERSION $PG_USER
+ - sudo ./ci/travis/install-libpqxx.sh $DIST
before_script:
diff --git a/AUTHORS.md b/AUTHORS.md
index 5edfb79..050ba7e 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -9,6 +9,7 @@
## Other contributors:
+* Aakash Sharma
* Adrien Pavie
* Anton Patrushev
* Daniel Wendt (Initial author)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0f5fcfd..de75fb8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,6 +5,7 @@ set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
set (SHARE_DIR "/usr/share/osm2pgrouting")
FIND_PACKAGE(PostgreSQL REQUIRED)
+find_package(LibPQXX REQUIRED)
FIND_PACKAGE(EXPAT REQUIRED)
FIND_PACKAGE(Boost)
@@ -16,35 +17,53 @@ endif(Boost_INCLUDE_DIRS)
FIND_PACKAGE(Boost COMPONENTS program_options REQUIRED)
-FILE(GLOB SRC "${CMAKE_SOURCE_DIR}/src/*.cpp" "${CMAKE_SOURCE_DIR}/src/*.h")
+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")
-set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wconversion -pedantic -Wextra -frounding-math -Wno-deprecated")
-
+set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wconversion -pedantic -Wextra -frounding-math -Wno-deprecated -fmax-errors=10")
+set (OSM2PGROUTING_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/include")
+message(STATUS "LIBPQXX_INCLUDE_DIRS: ${LIBPQXX_INCLUDE_DIRS}")
message(STATUS "POSTGRESQL_INCLUDE_DIR: ${POSTGRESQL_INCLUDE_DIR}")
message(STATUS "EXPAT_INCLUDE_DIRS: ${EXPAT_INCLUDE_DIRS}")
message(STATUS "Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
message(STATUS "POSTGRESQL_LIBRARIES: ${POSTGRESQL_LIBRARIES}")
message(STATUS "Boost_LIBRARIES: ${boost_LIBRARIES}")
+message(STATUS "LIBPQXX_LIBRARIES: ${LIBPQXX_LIBRARIES}")
+
+INCLUDE_DIRECTORIES(src
+ ${LIBPQXX_INCLUDE_DIRS}
+ ${POSTGRESQL_INCLUDE_DIR}
+ ${EXPAT_INCLUDE_DIRS}
+ ${Boost_INCLUDE_DIRS}
+ ${OSM2PGROUTING_INCLUDE_DIRS}
+ )
-INCLUDE_DIRECTORIES(src ${POSTGRESQL_INCLUDE_DIR} ${EXPAT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
-
-ADD_EXECUTABLE(osm2pgrouting ${SRC})
+ADD_EXECUTABLE(osm2pgrouting ${osm2pgrouting_lib_SOURCES})
-TARGET_LINK_LIBRARIES(osm2pgrouting ${POSTGRESQL_LIBRARIES} ${EXPAT_LIBRARIES} ${Boost_LIBRARIES} )
+TARGET_LINK_LIBRARIES(osm2pgrouting
+ ${LIBPQXX_LIBRARIES}
+ ${POSTGRESQL_LIBRARIES}
+ ${EXPAT_LIBRARIES}
+ ${Boost_LIBRARIES}
+ )
INSTALL(TARGETS osm2pgrouting
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}")
diff --git a/NEWS b/NEWS
index 56072f4..6e10eb7 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,12 @@
+osm2pgRouting 2.3.0
+
+* Cost should not return the same value
+* Added a points of Interest table
+* Some default one_way values are taken into consideration
+* Relations are also condsidered
+* New mapconfig_for_pedestrian.xml
+
+
osm2pgRouting 2.2.0
* Adding foreign keys to the tables.
diff --git a/Readme.md b/Readme.md
index 5d7befd..41bebd6 100644
--- a/Readme.md
+++ b/Readme.md
@@ -11,6 +11,7 @@ Before you can use this tool for importing Openstreetmap data you need to instal
3. pgrouting
4. boost
5. expat
+5. libpqxx
6. cmake
and to prepare a database.
@@ -38,6 +39,9 @@ Install some prerqeuisites
```
sudo apt-get install expat
sudo apt-get install libexpat1-dev
+sudo apt-get install libboost-dev
+sudo apt-get install libboost-program-options-dev
+sudo apt install libpqxx-dev
```
CMAKE options:
@@ -82,9 +86,7 @@ osm2pgrouting --f next-OSM-XML-File.osm --conf mapconfig.xml --dbname routing --
A complete list of arguments are:
```
-Allowed options:
-
-
+ osm2pgrouting --help
Allowed options:
Help:
@@ -103,15 +105,22 @@ General:
table names.
--suffix arg Suffix added at the end of the table
names.
- --addnodes Import the osm_nodes table.
+ --postgis Install postgis if not found.
+ --addnodes Import the osm_nodes, osm_ways &
+ osm_relations tables.
+ --attributes Include attributes information.
+ --tags Include tag information.
+ --chunk arg (=20000) Exporting chunk size.
--clean Drop previously created tables.
+ --no-index Do not create indexes (Use when indexes
+ are already created)
Database options:
- -d [ --dbname ] arg Name of your database (Required).
- -U [ --username ] arg (=postgres) Name of the user, which have write access
- to the database.
- -h [ --host ] arg (=localhost) Host of your postgresql database.
- -p [ --port ] arg (=5432) db_port of your database.
- -W [ --password ] arg Password for database access.
+ -d [ --dbname ] arg Name of your database (Required).
+ -U [ --username ] arg Name of the user, which have write access to
+ the database.
+ -h [ --host ] arg (=localhost) Host of your postgresql database.
+ -p [ --port ] arg (=5432) db_port of your database.
+ -W [ --password ] arg Password for database access.
```
diff --git a/ci/travis/install-libpqxx.sh b/ci/travis/install-libpqxx.sh
new file mode 100755
index 0000000..33ad002
--- /dev/null
+++ b/ci/travis/install-libpqxx.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# ------------------------------------------------------------------------------
+# Travis CI scripts
+# Copyright(c) pgRouting Contributors
+#
+# Install osm2pgrouting prerequesits
+# ------------------------------------------------------------------------------
+
+set -e
+
+
+DISTRIBUTION="$1"
+
+if [[ -z "$DISTRIBUTION=" ]] ; then
+ exit 1
+fi
+
+
+if [[ "$DISTRIBUTION" = "precise" ]] ; then
+ sudo apt-get install -y libpqxx3-dev
+elif [[ "$DISTRIBUTION" = "trusty" ]] ; then
+ sudo sudo sudo apt-get install -y libpqxx-dev
+else
+ exit 1
+fi
+
diff --git a/ci/travis/osm2pgrouting_build.sh b/ci/travis/osm2pgrouting_build.sh
index 059181b..997b097 100755
--- a/ci/travis/osm2pgrouting_build.sh
+++ b/ci/travis/osm2pgrouting_build.sh
@@ -9,8 +9,10 @@
# exit script on error
set -e
-# build pgRouting
-cmake -DPOSTGRESQL_VERSION=$POSTGRESQL_VERSION
+# build osm2pgrouting
+mkdir build
+cd build
+cmake ..
make
sudo make install
-
+cd ..
diff --git a/cmake/FindLibPQXX.cmake b/cmake/FindLibPQXX.cmake
new file mode 100644
index 0000000..eec3360
--- /dev/null
+++ b/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/include/configuration/configuration.h b/include/configuration/configuration.h
new file mode 100644
index 0000000..18fb043
--- /dev/null
+++ b/include/configuration/configuration.h
@@ -0,0 +1,99 @@
+/***************************************************************************
+ * Copyright (C) 2016 by pgRouting developers *
+ * project at pgrouting.org *
+ * *
+ * 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 t &or 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef SRC_CONFIGURATION_H_
+#define SRC_CONFIGURATION_H_
+
+#include <string>
+#include <map>
+#include <boost/lexical_cast.hpp>
+#include "configuration/tag_key.h"
+#include "configuration/tag_value.h"
+#include "osm_elements/osm_tag.h"
+
+namespace osm2pgr {
+class Configuration {
+ public:
+ Configuration() = default;
+
+ /** @brief add group of tag_key + all the tag_values
+ *
+ * @param[in] t_key Tag_key found in the configuration
+ */
+ void add_tag_key(const Tag_key &t_key);
+
+ /** @brief retrieves the Tag_value (attrributes
+ *
+ * @param[in] tag Tag found in the configuration
+ * @returns Tag_value
+ */
+ const Tag_value& tag_value(const Tag &tag) const;
+
+ /* Is the (key, value) pair in the configuration?
+ *
+ *
+ * @param[in] tag Tag (key, value) pair
+ */
+ bool has_tag(const Tag &tag) const;
+
+ /** retrieves the maxspeed based on the tag
+ *
+ * if the (key,value) has a value this is returned
+ * else if the (key, *) has a value this is returned
+ * else 50 is returned
+ */
+
+ double maxspeed(const Tag &tag) const;
+ double maxspeed_forward(const Tag &tag) const;
+ double maxspeed_backward(const Tag &tag) const;
+
+ /** retrieves the priority based on the tag
+ *
+ * if the (key,value) has a value this is returned
+ * else if the (key, *) has a value this is returned
+ * else 0 is returned
+ */
+
+ double priority(const Tag &tag) const;
+
+ /*
+ * data to be exported to configuration TABLE
+ */
+ const std::map<std::string, Tag_key>& types() const {return m_Tag_keys;}
+
+ private:
+ /** @brief is the tag key in the configuration file
+ *
+ * @param[in] key tag_key name="key"
+ */
+
+ bool has_tag_key(const std::string &key) const;
+ const Tag_key& tag_key(const Tag &tag) const;
+
+
+ private:
+ std::map<std::string, Tag_key> m_Tag_keys;
+};
+
+
+} // end namespace osm2pgr
+#endif // SRC_CONFIGURATION_H_
+
+
+
diff --git a/src/Type.h b/include/configuration/tag_key.h
similarity index 67%
rename from src/Type.h
rename to include/configuration/tag_key.h
index 174f101..35f2a4d 100644
--- a/src/Type.h
+++ b/include/configuration/tag_key.h
@@ -24,45 +24,39 @@
#include <map>
#include <cstdint>
+#include <cassert>
#include <string>
-#include "./Class.h"
+#include "./tag_value.h"
namespace osm2pgr {
-class Type {
+class Tag_key : Element {
public:
- Type() = default;
- Type(const Type &) = default;
- /**
+ Tag_key() = default;
+ Tag_key(const Tag_key &) = default;
+ /** @brief build it
* @param atts attributes read py the parser
*/
- explicit Type(const char **atts);
- inline int64_t id() const {return m_id;}
- inline std::string name() const {return m_name;}
- void add_class(const char **atts);
- std::map<std::string, Class> classes() const {
- return m_Classes;
- }
- std::map<std::string, Class>& classes() {
- return m_Classes;
- }
+ explicit Tag_key(const char **atts);
+ void add_tag_value(const Tag_value &p_values);
- inline bool has_class(const std::string &class_name) const {
- return m_Classes.count(class_name);
- }
- private:
- /**
- * saves the classes of the type
- * @param pClass class
- */
- void AddClass(const Class &pClass);
+ /* to have or not to have */
+ bool has(const Tag &tag, const std::string &str) const;
+ bool has_tag_value(const Tag &tag) const;
+
+ /* get it*/
+ std::string get(const Tag &tag, const std::string &str) const;
+ const Tag_value& tag_value(const Tag &tag) const;
+ inline int64_t id() const {return osm_id();}
+ inline std::string name() const {return get_attribute("name");}
+
+ /* used in the export function */
+ std::vector<std::string> values(
+ const std::vector<std::string> &columns) const;
private:
- std::map<std::string, Class> m_Classes;
- int64_t m_id;
- std::string m_name;
- std::map<std::string, std::string> m_tags;
+ std::map<std::string, Tag_value> m_Tag_values;
};
} // namespace osm2pgr
diff --git a/src/Class.h b/include/configuration/tag_value.h
similarity index 76%
rename from src/Class.h
rename to include/configuration/tag_value.h
index 23e3c54..615bc4f 100644
--- a/src/Class.h
+++ b/include/configuration/tag_value.h
@@ -21,29 +21,29 @@
#ifndef SRC_CLASS_H_
#define SRC_CLASS_H_
+#include <boost/lexical_cast.hpp>
+#include <osm_elements/osm_element.h>
+#include <cassert>
#include <map>
#include <string>
+#include <vector>
namespace osm2pgr {
-class Class {
+class Tag_value : public Element {
public:
- Class() = default;
- Class(const Class &) = default;
- explicit Class(const char ** attributes);
-
-
- inline int64_t id() const {return m_id;}
- inline std::string name() const {return m_name;}
- inline double priority() const {return m_priority;}
- inline double default_maxspeed() const {return m_default_maxspeed;}
-
- private:
- int64_t m_id;
- std::string m_name;
- double m_priority;
- double m_default_maxspeed;
- std::map<std::string, std::string> m_tags;
+ Tag_value() = default;
+ Tag_value(const Tag_value &) = default;
+ /** @brief build it */
+ explicit Tag_value(const char ** attributes);
+
+
+ /** @brief get it */
+ inline int64_t id() const {return osm_id();}
+ std::string name() const;
+ std::string get(const std::string &str) const;
+ std::vector<std::string> export_values() const;
+
};
diff --git a/include/database/Export2DB.h b/include/database/Export2DB.h
new file mode 100644
index 0000000..c83cdad
--- /dev/null
+++ b/include/database/Export2DB.h
@@ -0,0 +1,153 @@
+/***************************************************************************
+ * Copyright (C) 2016 by pgRouting developers *
+ * project at pgrouting.org *
+ * *
+ * 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 t &or 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+
+#ifndef SRC_EXPORT2DB_H_
+#define SRC_EXPORT2DB_H_
+
+#include <pqxx/pqxx>
+#include <libpq-fe.h>
+#include <map>
+#include <vector>
+#include <string>
+
+#include "osm_elements/Node.h"
+#include "osm_elements/Way.h"
+#include "osm_elements/Relation.h"
+#include "configuration/configuration.h"
+#include "utilities/prog_options.h"
+#include "database/table_management.h"
+
+namespace osm2pgr {
+
+/**
+ * This class connects to a postgresql database. For using this class,
+ * you also need to install postgis and pgrouting
+ */
+
+class Export2DB {
+ public:
+ typedef std::vector<Node> Nodes;
+ typedef std::vector<Way> Ways;
+ typedef std::vector<Relation> Relations;
+
+ /**
+ * Constructor
+ * @param vm variable map holding the configuration
+ * @param db_conn conection string
+ *
+ */
+ explicit Export2DB(const po::variables_map &vm, const std::string &db_conn);
+
+ /**
+ * Destructor
+ * closes the connection to the database
+ */
+ ~Export2DB();
+
+#if 1
+ //! connects to database
+ int connect();
+#endif
+
+ bool has_extension(const std::string &name) const;
+#ifndef NDBEUG
+ bool install_postGIS() const;
+#endif
+
+ //! creates needed tables and geometries
+ void createTables() const;
+
+
+ /** @brief export values to osm_* table
+ *
+ * T must have:
+ * T.values
+ *
+ * @param[in] items vector of values to be inserted into
+ * @param[in] table
+ */
+ template <typename T>
+ void export_osm (
+ std::vector<T> &items,
+ const std::string &table) const {
+ auto osm_table = m_tables.get_table(table);
+ std::vector<std::string> values(items.size(), "");
+
+ size_t i(0);
+ for (auto it = items.begin(); it != items.end(); ++it, ++i) {
+ auto item = *it;
+ values[i] = tab_separated(item.values(osm_table.columns(), true));
+ }
+
+ export_osm(values, osm_table);
+ }
+
+ void export_configuration(
+ const std::map<std::string, Tag_key>& items) const;
+
+ void exportWays(
+ const Ways &ways,
+ const Configuration &config) const;
+
+ void dropTables() const;
+ void createFKeys() const;
+ void process_pois() const;
+
+ private:
+
+ void export_osm(
+ const std::vector<std::string> &values,
+ const Table &table) const;
+
+ void process_section(const std::string &ways_columns, pqxx::work &Xaction) const;
+
+ void fill_vertices_table(
+ const std::string &table,
+ const std::string &vertices_tab,
+ pqxx::work &Xaction) const;
+
+ void fill_source_target(
+ const std::string &table,
+ const std::string &vertices_tab,
+ pqxx::work &Xaction) const;
+
+ int64_t get_val(const std::string sql) const;
+ void execute(const std::string sql) const;
+
+ Table configuration() const {return m_tables.configuration();}
+ Table vertices() const {return m_tables.vertices();}
+ Table ways() const {return m_tables.ways();}
+ Table pois() const {return m_tables.pois();}
+ Table osm_ways() const {return m_tables.osm_ways();}
+ Table osm_nodes() const {return m_tables.osm_nodes();}
+ Table osm_relations() const {return m_tables.osm_relations();}
+
+ private:
+ po::variables_map m_vm;
+
+ std::string conninf;
+
+ Tables m_tables;
+
+};
+} // namespace osm2pgr
+
+#endif // SRC_EXPORT2DB_H_
diff --git a/include/database/table_management.h b/include/database/table_management.h
new file mode 100644
index 0000000..18f06af
--- /dev/null
+++ b/include/database/table_management.h
@@ -0,0 +1,161 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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 **/
+#pragma once
+#include <string>
+#include "utilities/prog_options.h"
+
+namespace osm2pgr {
+
+class Table {
+ public:
+ Table() = default;
+ Table(const Table &) = default;
+ Table(
+ const std::string &schema,
+ const std::string &name,
+ const std::string &full_name,
+
+ const std::string &create_str,
+ const std::string &other_columns,
+ const std::string &geometry
+ );
+
+ void set_columns(const std::vector<std::string> &columns);
+
+ /** @brief prefixNameSufix */
+ inline std::string table_name() const {
+ return m_full_name;
+ }
+
+
+ /** @brief schema.prefixNameSufix
+ *
+ * schema.prefixNameSufix
+ * OR
+ * prefixNameSufix
+ *
+ */
+ std::string addSchema() const;
+ std::string temp_name() const;
+ std::string name() const {return m_name;};
+ std::string full_name() const {return m_full_name;};
+
+ /** sql queries
+ */
+ std::string primary_key(const std::string &column) const;
+ std::string unique(const std::string &column) const;
+ std::string foreign_key(
+ const std::string &column,
+ const Table &table,
+ const std::string &table_column) const;
+ std::string gist_index() const;
+
+ inline std::vector<std::string> columns() const {
+ return m_columns;
+ }
+ std::string sql(int i) const {return m_sql[i];}
+
+
+ std::string tmp_create() const;
+ std::string create() const;
+ std::string drop() const;
+
+ /* modifier */
+ void add_sql(const string& sql) {
+ m_sql.push_back(sql);
+ }
+
+ private:
+ std::string m_name;
+ std::string m_schema;
+ std::string m_full_name;
+
+ std::string m_create;
+ std::string m_other_columns;
+ std::string m_constraint;
+ std::string m_geometry;
+ std::vector<std::string> m_columns;
+
+ /** aditional sqls (for pois) to keep code clean*/
+ std::vector<std::string> m_sql;
+};
+
+
+
+
+class Tables {
+ public:
+ Tables(const po::variables_map &vm);
+
+ const Table& get_table(const std::string &name) const {
+ if (name == "osm_nodes") return osm_nodes();
+ else if (name == "osm_ways") return osm_ways();
+ else if (name == "osm_relations") return osm_relations();
+ else if (name == "configuration") return configuration();
+ else if (name == "pointsofinterest") return pois();
+ else if (name == "ways") return ways();
+ else return vertices();
+ }
+
+ std::string post_process(const Table &table) const;
+
+
+
+ po::variables_map m_vm;
+
+ private:
+ /*
+ * Conpulsory tables
+ */
+ Table m_ways;
+ Table m_ways_vertices_pgr;
+ Table m_points_of_interest;
+ Table m_configuration;
+
+ /*
+ * Optional tables
+ */
+ Table m_osm_nodes;
+ Table m_osm_ways;
+ Table m_osm_relations;
+
+ public:
+ const Table& ways() const {return m_ways;}
+ const Table& vertices() const {return m_ways_vertices_pgr;}
+ const Table& pois() const {return m_points_of_interest;}
+ const Table& configuration() const {return m_configuration;}
+ const Table& osm_nodes() const {return m_osm_nodes;}
+ const Table& osm_ways() const {return m_osm_ways;}
+ const Table& osm_relations() const {return m_osm_relations;}
+
+ private:
+ Table osm_nodes_config() const;
+ Table pois_config() const;
+ Table osm_ways_config() const;
+ Table osm_relations_config() const;
+ Table configuration_config() const;
+ Table ways_config() const;
+ Table ways_vertices_pgr_config() const;
+};
+
+}
+
+
diff --git a/src/Node.h b/include/osm_elements/Node.h
similarity index 92%
rename from src/Node.h
rename to include/osm_elements/Node.h
index 24e6aaa..281c17e 100644
--- a/src/Node.h
+++ b/include/osm_elements/Node.h
@@ -66,11 +66,18 @@ class Node : public Element {
* @param atts attributes read py the parser
*/
explicit Node(const char **atts);
- inline std::string geom_str(std::string separator) {
+ ~Node() {};
+
+ inline std::string geom_str(const std::string separator) const {
return get_attribute("lon") + separator + get_attribute("lat");
}
+ inline std::string lat() {return get_attribute("lat");}
+ inline std::string lon() {return get_attribute("lon");}
+
+ void tag_config(const Tag &tag);
+
- inline std::string point_geometry() {
+ std::string get_geometry() const {
return
std::string("srid=4326; POINT(")
+ geom_str(" ") + ")";
diff --git a/include/osm_elements/OSMDocument.h b/include/osm_elements/OSMDocument.h
new file mode 100644
index 0000000..62d4a2c
--- /dev/null
+++ b/include/osm_elements/OSMDocument.h
@@ -0,0 +1,159 @@
+/***************************************************************************
+ * Copyright (C) 2016 by pgRouting developers *
+ * project at pgrouting.org *
+ * *
+ * 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 t &or 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+
+#ifndef SRC_OSMDOCUMENT_H_
+#define SRC_OSMDOCUMENT_H_
+
+#include <iostream>
+#include <map>
+#include <vector>
+#include "utilities/utilities.h"
+#include "configuration/configuration.h"
+#include "utilities/prog_options.h"
+#include "database/Export2DB.h"
+
+namespace osm2pgr {
+
+
+class Node;
+class Way;
+class Relation;
+
+/**
+ An osm-document.
+*/
+class OSMDocument {
+ public:
+ typedef std::vector<Node> Nodes;
+ typedef std::vector<Way> Ways;
+ typedef std::vector<Relation> Relations;
+
+ //! Constructor
+ OSMDocument(
+ const Configuration& config,
+ const po::variables_map &vm,
+ const Export2DB &db_conn,
+ size_t lines);
+
+ inline size_t lines() const {return m_lines;}
+
+ //! Do the configuration has the @b tag ?
+ inline bool config_has_tag(const Tag &tag) const {
+ return m_rConfig.has_tag(tag);
+ }
+
+ inline double priority(const Tag &tag) const {
+ return m_rConfig.priority(tag);
+ }
+
+ inline double maxspeed(const Tag &tag) const {
+ return m_rConfig.maxspeed(tag);
+ }
+
+ const Nodes& nodes() const {return m_nodes;}
+ const Ways& ways() const {return m_ways;}
+ const Relations& relations() const {return m_relations;}
+
+ void AddNode(const Node &n);
+ void AddWay(const Way &w);
+ void AddRelation(const Relation &r);
+ void endOfFile() const;
+
+ //! find node by using an ID
+ bool has_node(int64_t nodeRefId) const;
+ Node* FindNode(int64_t nodeRefId);
+
+ bool has_way(int64_t way_id) const;
+ Way* FindWay(int64_t way_id);
+
+
+ void add_node(Way &way, const char **atts);
+
+ /**
+ * add the configuration tag used for the speeds
+ */
+ void add_config(Element *osm_element, const Tag &tag) const;
+
+ inline uint16_t nodeErrs() const {return m_nodeErrs;}
+
+ private:
+ template <typename T>
+ bool
+ do_export_osm(const T &container) {
+ return m_vm.count("addnodes") && (container.size() % m_chunk_size) == 0;
+ }
+
+
+ void wait_child() const;
+
+ template <typename T>
+ void
+ osm_table_export(const T &osm_items, const std::string &table) const {
+ if (osm_items.empty()) return;
+
+ if (m_vm.count("addnodes")) {
+#if 0
+ auto pid = fork();
+ if (pid < 0) {
+ std::cerr << "Failed to fork" << endl;
+ exit(1);
+ }
+ if (pid > 0) return;
+#endif
+ }
+ auto residue = osm_items.size() % m_chunk_size;
+ size_t start = residue? osm_items.size() - residue : osm_items.size() - m_chunk_size;
+ auto export_items = T(osm_items.begin() + start, osm_items.end());
+
+ m_db_conn.export_osm(export_items, table);
+
+ if (m_vm.count("addnodes")) {
+#if 0
+ /*
+ * finish the child process
+ */
+ _exit(0);
+#endif
+ }
+ }
+
+ void export_pois() const;
+
+
+ private:
+ // ! parsed nodes TODO change to sorted vector
+ Nodes m_nodes;
+ //! parsed ways
+ Ways m_ways;
+ //! parsed relations
+ Relations m_relations;
+
+ const Configuration& m_rConfig;
+ po::variables_map m_vm;
+ const Export2DB &m_db_conn;
+
+ size_t m_chunk_size;
+ uint16_t m_nodeErrs;
+ size_t m_lines;
+};
+
+} // end namespace osm2pgr
+#endif // SRC_OSMDOCUMENT_H_
diff --git a/src/Relation.h b/include/osm_elements/Relation.h
similarity index 96%
rename from src/Relation.h
rename to include/osm_elements/Relation.h
index 7e50286..e73bdf5 100644
--- a/src/Relation.h
+++ b/include/osm_elements/Relation.h
@@ -58,15 +58,18 @@ class Relation : public Element{
*/
explicit Relation(const char ** atts);
Relation() = delete;
+ ~Relation() {};
Relation(const Relation&) = default;
std::vector<int64_t> way_refs() const {return m_WayRefs;}
std::vector<int64_t>& way_refs() {return m_WayRefs;}
+ std::string get_geometry() const {return std::string("");}
/**
* saves the nodes of the way
* @param atts member attributes read py the parser
*/
int64_t add_member(const char **atts);
+ std::string members_str() const;
private:
std::vector<int64_t> m_WayRefs;
diff --git a/src/Way.h b/include/osm_elements/Way.h
similarity index 90%
rename from src/Way.h
rename to include/osm_elements/Way.h
index 3ce8362..b5d4e11 100644
--- a/src/Way.h
+++ b/include/osm_elements/Way.h
@@ -54,6 +54,7 @@ namespace osm2pgr {
class Way : public Element {
public:
Way() = default;
+ ~Way() {};
/**
* @param atts attributes read py the parser
@@ -61,11 +62,14 @@ class Way : public Element {
explicit Way(const char **atts);
Tag add_tag(const Tag &tag);
void add_node(Node* node);
+ void add_node(int64_t node_id);
std::vector<Node*>& nodeRefs() {return m_NodeRefs;}
const std::vector<Node*> nodeRefs() const {return m_NodeRefs;}
+ std::string members_str() const;
+
public:
inline void maxspeed_forward(double p_max) {m_maxspeed_forward = p_max;}
inline void maxspeed_backward(double p_max) {m_maxspeed_backward = p_max;}
@@ -81,17 +85,15 @@ class Way : public Element {
inline double maxspeed_forward() const {return m_maxspeed_forward;}
inline double maxspeed_backward() const { return m_maxspeed_backward;}
- std::string geometry_str() const;
+ std::string get_geometry() const;
std::string length_str() const;
inline std::string maxspeed_forward_str() const {
- return boost::lexical_cast<std::string>(
- static_cast<int>(m_maxspeed_forward));
+ return boost::lexical_cast<std::string>(m_maxspeed_forward);
}
inline std::string maxspeed_backward_str() const {
- return boost::lexical_cast<std::string>(
- static_cast<int>(m_maxspeed_backward));
+ return boost::lexical_cast<std::string>(m_maxspeed_backward);
}
@@ -120,11 +122,14 @@ class Way : public Element {
private:
+ /** references to node that its on the file */
std::vector<Node*> m_NodeRefs;
+ /** node identifiers found as part of the way */
+ std::vector<int64_t> m_node_ids;
+
double m_maxspeed_forward;
double m_maxspeed_backward;
-
std::string m_oneWay;
};
diff --git a/src/osm_element.h b/include/osm_elements/osm_element.h
similarity index 86%
rename from src/osm_element.h
rename to include/osm_elements/osm_element.h
index 7007a86..3b32a6c 100644
--- a/src/osm_element.h
+++ b/include/osm_elements/osm_element.h
@@ -24,6 +24,7 @@
#pragma once
#include <string>
+#include <vector>
#include <map>
#include "./osm_tag.h"
@@ -51,18 +52,22 @@ class Element {
* @param atts attributes pointer returned by the XML parser
*/
explicit Element(const char **atts);
+ virtual ~Element() {};
+
Tag add_tag(const Tag &);
inline int64_t osm_id() const {return m_osm_id;}
inline bool visible() const {return m_visible;}
- inline void tag_config(const Tag &tag) {m_tag_config = tag;}
+ virtual void tag_config(const Tag &tag);
inline Tag tag_config() const {return m_tag_config;}
+ bool is_tag_configured() const;
std::string attributes_str() const;
std::string tags_str() const;
+ virtual std::string get_geometry() const {return "";}
bool has_attribute(const std::string&) const;
std::string get_attribute(const std::string&) const;
std::map<std::string, std::string>& attributes() {return m_attributes;}
@@ -73,11 +78,19 @@ class Element {
bool has_tag(const std::string&) const;
std::string get_tag(const std::string&) const;
+
+ bool has_tags() const {return !m_tags.empty();}
std::map<std::string, std::string>& tags() {return m_tags;}
const std::map<std::string, std::string> tags() const {return m_tags;}
+ std::vector<std::string> values(
+ const std::vector<std::string> &columns,
+ bool is_hstore) const;
+ virtual std::string members_str() const {return std::string();};
+
protected:
// ! OSM ID of the element
+ // or id of a configuraton
int64_t m_osm_id;
bool m_visible;
Tag m_tag_config;
diff --git a/src/osm_tag.h b/include/osm_elements/osm_tag.h
similarity index 100%
rename from src/osm_tag.h
rename to include/osm_elements/osm_tag.h
diff --git a/src/ConfigurationParserCallback.h b/include/parser/ConfigurationParserCallback.h
similarity index 98%
rename from src/ConfigurationParserCallback.h
rename to include/parser/ConfigurationParserCallback.h
index 224963b..9eaf306 100644
--- a/src/ConfigurationParserCallback.h
+++ b/include/parser/ConfigurationParserCallback.h
@@ -36,7 +36,7 @@
namespace osm2pgr {
class Configuration;
-class Type;
+class Tag_key;
/**
Parser callback for configuration files
@@ -55,7 +55,7 @@ class ConfigurationParserCallback : public xml::XMLParserCallback {
Configuration& m_config;
//! current type, which will be parsed
- Type *m_current;
+ Tag_key* m_current;
virtual void StartElement(const char *name, const char** atts);
diff --git a/src/OSMDocumentParserCallback.h b/include/parser/OSMDocumentParserCallback.h
similarity index 97%
rename from src/OSMDocumentParserCallback.h
rename to include/parser/OSMDocumentParserCallback.h
index 5b434ac..45adc09 100644
--- a/src/OSMDocumentParserCallback.h
+++ b/include/parser/OSMDocumentParserCallback.h
@@ -59,8 +59,7 @@ class OSMDocumentParserCallback :
/**
* Constructor
*/
- explicit OSMDocumentParserCallback(OSMDocument& doc)
- :
+ explicit OSMDocumentParserCallback(OSMDocument& doc) :
m_rDocument(doc),
m_pActRelation(0),
last_node(nullptr),
diff --git a/src/XMLParser.h b/include/parser/XMLParser.h
similarity index 100%
rename from src/XMLParser.h
rename to include/parser/XMLParser.h
diff --git a/include/utilities/handle_pgpass.h b/include/utilities/handle_pgpass.h
new file mode 100644
index 0000000..cc661eb
--- /dev/null
+++ b/include/utilities/handle_pgpass.h
@@ -0,0 +1,29 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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 <boost/program_options.hpp>
+#include <string>
+
+namespace po = boost::program_options;
+
+
+void
+handle_pgpass(po::variables_map &vm);
diff --git a/src/print_progress.h b/include/utilities/print_progress.h
similarity index 97%
rename from src/print_progress.h
rename to include/utilities/print_progress.h
index 709c0ff..ecf66ea 100644
--- a/src/print_progress.h
+++ b/include/utilities/print_progress.h
@@ -47,6 +47,6 @@ print_progress(T1 wantProgress, T2 currentProgress) {
std::cout << "\r"
<< bar
<< " (" << static_cast<int>(100 * percent) << "%)"
- << std::flush;
+ << " Total porcessed: " << currentProgress << std::flush;
}
#endif // SRC_PRINT_PROGRESS_H_
diff --git a/src/prog_options.h b/include/utilities/prog_options.h
similarity index 100%
rename from src/prog_options.h
rename to include/utilities/prog_options.h
diff --git a/include/utilities/utilities.h b/include/utilities/utilities.h
new file mode 100644
index 0000000..f609a1b
--- /dev/null
+++ b/include/utilities/utilities.h
@@ -0,0 +1,30 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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 <string>
+#include <vector>
+
+
+std::string
+comma_separated(const std::vector<std::string> &columns);
+std::string
+tab_separated(const std::vector<std::string> &columns);
diff --git a/mapconfig.xml b/mapconfig.xml
index 2ee4f9d..3e750e7 100644
--- a/mapconfig.xml
+++ b/mapconfig.xml
@@ -1,48 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
- <type name="highway" id="1">
- <class name="motorway" id="101" />
- <class name="motorway_link" id="102" />
- <class name="motorway_junction" id="103" />
- <class name="trunk" id="104" />
- <class name="trunk_link" id="105" />
- <class name="primary" id="106" />
- <class name="primary_link" id="107" />
- <class name="secondary" id="108" />
- <class name="secondary_link" id="124" />
- <class name="tertiary" id="109" />
- <class name="tertiary_link" id="125" />
- <class name="residential" id="110" />
- <class name="living_street" id="111" />
- <class name="service" id="112" />
- <class name="track" id="113" />
- <class name="pedestrian" id="114" />
- <class name="services" id="115" />
- <class name="bus_guideway" id="116" />
- <class name="path" id="117" />
- <class name="cycleway" id="118" />
- <class name="footway" id="119" />
- <class name="bridleway" id="120" />
- <class name="byway" id="121" />
- <class name="steps" id="122" />
+ <tag_name name="highway" id="1">
+ <tag_value name="motorway" id="101" />
+ <tag_value name="motorway_link" id="102" />
+ <tag_value name="motorway_junction" id="103" />
+ <tag_value name="trunk" id="104" />
+ <tag_value name="trunk_link" id="105" />
+ <tag_value name="primary" id="106" />
+ <tag_value name="primary_link" id="107" />
+ <tag_value name="secondary" id="108" />
+ <tag_value name="secondary_link" id="124" />
+ <tag_value name="tertiary" id="109" />
+ <tag_value name="tertiary_link" id="125" />
+ <tag_value name="residential" id="110" />
+ <tag_value name="living_street" id="111" />
+ <tag_value name="service" id="112" />
+ <tag_value name="track" id="113" />
+ <tag_value name="pedestrian" id="114" />
+ <tag_value name="services" id="115" />
+ <tag_value name="bus_guideway" id="116" />
+ <tag_value name="path" id="117" />
+ <tag_value name="cycleway" id="118" />
+ <tag_value name="footway" id="119" />
+ <tag_value name="bridleway" id="120" />
+ <tag_value name="byway" id="121" />
+ <tag_value name="steps" id="122" />
- <class name="unclassified" id="123" />
- <class name="road" id="100" />
- </type>
- <type name="cycleway" id="2">
- <class name="lane" id="201" />
- <class name="track" id="202" />
- <class name="opposite_lane" id="203" />
- <class name="opposite" id="204" />
- </type>
- <type name="tracktype" id="3">
- <class name="grade1" id="301" />
- <class name="grade2" id="302" />
- <class name="grade3" id="303" />
- <class name="grade4" id="304" />
- <class name="grade5" id="305" />
- </type>
- <type name="junction" id="4">
- <class name="roundabout" id="401" />
- </type>
+ <tag_value name="unclassified" id="123" />
+ <tag_value name="road" id="100" />
+ </tag_name>
+ <tag_name name="cycleway" id="2">
+ <tag_value name="lane" id="201" />
+ <tag_value name="track" id="202" />
+ <tag_value name="opposite_lane" id="203" />
+ <tag_value name="opposite" id="204" />
+ </tag_name>
+ <tag_name name="tracktype" id="3">
+ <tag_value name="grade1" id="301" />
+ <tag_value name="grade2" id="302" />
+ <tag_value name="grade3" id="303" />
+ <tag_value name="grade4" id="304" />
+ <tag_value name="grade5" id="305" />
+ </tag_name>
+ <tag_name name="junction" id="4">
+ <tag_value name="roundabout" id="401" />
+ </tag_name>
</configuration>
diff --git a/mapconfig_for_bicycles.xml b/mapconfig_for_bicycles.xml
index 4a7b7f5..eea8526 100644
--- a/mapconfig_for_bicycles.xml
+++ b/mapconfig_for_bicycles.xml
@@ -1,60 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
- <type name="cycleway" id="1">
- <class name="track" priority="1.0" id="101" />
- <class name="lane" priority="1.5" id="102" />
- <class name="opposite_lane" priority="1.5" id="103" />
- <class name="opposite" priority="1.5" id="104" />
- <class name="shared_lane" priority="1.6" id="105" />
- <class name="shared" priority="1.6" id="106" />
- <class name="share_busway" priority="1.6" id="107" />
- </type>
- <type name="cycleway:right" id="2">
- <class name="track" priority="1.0" id="201" />
- <class name="lane" priority="1.5" id="202" />
- <class name="opposite_lane" priority="1.5" id="203" />
- <class name="opposite" priority="1.5" id="204" />
- <class name="shared_lane" priority="1.6" id="205" />
- <class name="shared" priority="1.6" id="206" />
- <class name="share_busway" priority="1.6" id="207" />
- </type>
- <type name="cycleway:left" id="3">
- <class name="track" priority="1.0" id="301" />
- <class name="lane" priority="1.5" id="302" />
- <class name="opposite_lane" priority="1.5" id="303" />
- <class name="opposite" priority="1.5" id="304" />
- <class name="shared_lane" priority="1.6" id="305" />
- <class name="shared" priority="1.6" id="306" />
- <class name="share_busway" priority="1.6" id="307" />
- </type>
- <type name="tracktype" id="4">
- <class name="grade1" priority="1.0" id="401" />
- <class name="grade2" priority="1.1" id="402" />
- <class name="grade3" priority="1.2" id="403" />
- <class name="grade4" priority="1.3" id="404" />
- <class name="grade5" priority="1.4" id="405" />
- </type>
- <type name="highway" id="5">
- <class name="cycleway" priority="1.0" id="501" />
- <class name="path" priority="1.1" id="502" />
- <class name="pedestrian" priority="1.1" id="503" />
- <class name="footway" priority="1.1" id="504" />
- <class name="bridleway" priority="1.3" id="505" />
- <class name="track" priority="1.0" id="506" />
- <class name="living_street" priority="2.0" id="507" />
- <class name="service" priority="2.0" id="508" />
- <class name="residential" priority="2.2" id="509" />
- <class name="unclassified" priority="2.3" id="510" />
- <class name="tertiary_link" priority="2.5" id="511" />
- <class name="tertiary" priority="2.5" id="512" />
- <class name="services" priority="2.7" id="513" />
- <class name="secondary_link" priority="3.0" id="514" />
- <class name="secondary" priority="3.0" id="515" />
- <class name="primary_link" priority="3.5" id="516" />
- <class name="primary" priority="3.5" id="517" />
- <class name="road" priority="4.0" id="500" />
- </type>
- <type name="junction" id="6">
- <class name="roundabout" priority="2.5" id="601" />
- </type>
-</configuration>
\ No newline at end of file
+ <tag_name name="cycleway" id="1">
+ <tag_value name="track" priority="1.0" id="101" />
+ <tag_value name="lane" priority="1.5" id="102" />
+ <tag_value name="opposite_lane" priority="1.5" id="103" />
+ <tag_value name="opposite" priority="1.5" id="104" />
+ <tag_value name="shared_lane" priority="1.6" id="105" />
+ <tag_value name="shared" priority="1.6" id="106" />
+ <tag_value name="share_busway" priority="1.6" id="107" />
+ </tag_name>
+ <tag_name name="cycleway:right" id="2">
+ <tag_value name="track" priority="1.0" id="201" />
+ <tag_value name="lane" priority="1.5" id="202" />
+ <tag_value name="opposite_lane" priority="1.5" id="203" />
+ <tag_value name="opposite" priority="1.5" id="204" />
+ <tag_value name="shared_lane" priority="1.6" id="205" />
+ <tag_value name="shared" priority="1.6" id="206" />
+ <tag_value name="share_busway" priority="1.6" id="207" />
+ </tag_name>
+ <tag_name name="cycleway:left" id="3">
+ <tag_value name="track" priority="1.0" id="301" />
+ <tag_value name="lane" priority="1.5" id="302" />
+ <tag_value name="opposite_lane" priority="1.5" id="303" />
+ <tag_value name="opposite" priority="1.5" id="304" />
+ <tag_value name="shared_lane" priority="1.6" id="305" />
+ <tag_value name="shared" priority="1.6" id="306" />
+ <tag_value name="share_busway" priority="1.6" id="307" />
+ </tag_name>
+ <tag_name name="tracktype" id="4">
+ <tag_value name="grade1" priority="1.0" id="401" />
+ <tag_value name="grade2" priority="1.1" id="402" />
+ <tag_value name="grade3" priority="1.2" id="403" />
+ <tag_value name="grade4" priority="1.3" id="404" />
+ <tag_value name="grade5" priority="1.4" id="405" />
+ </tag_name>
+ <tag_name name="highway" id="5">
+ <tag_value name="cycleway" priority="1.0" id="501" />
+ <tag_value name="path" priority="1.1" id="502" />
+ <tag_value name="pedestrian" priority="1.1" id="503" />
+ <tag_value name="footway" priority="1.1" id="504" />
+ <tag_value name="bridleway" priority="1.3" id="505" />
+ <tag_value name="track" priority="1.0" id="506" />
+ <tag_value name="living_street" priority="2.0" id="507" />
+ <tag_value name="service" priority="2.0" id="508" />
+ <tag_value name="residential" priority="2.2" id="509" />
+ <tag_value name="unclassified" priority="2.3" id="510" />
+ <tag_value name="tertiary_link" priority="2.5" id="511" />
+ <tag_value name="tertiary" priority="2.5" id="512" />
+ <tag_value name="services" priority="2.7" id="513" />
+ <tag_value name="secondary_link" priority="3.0" id="514" />
+ <tag_value name="secondary" priority="3.0" id="515" />
+ <tag_value name="primary_link" priority="3.5" id="516" />
+ <tag_value name="primary" priority="3.5" id="517" />
+ <tag_value name="road" priority="4.0" id="500" />
+ </tag_name>
+ <tag_name name="junction" id="6">
+ <tag_value name="roundabout" priority="2.5" id="601" />
+ </tag_name>
+</configuration>
diff --git a/mapconfig_for_cars.xml b/mapconfig_for_cars.xml
index d3084b0..899d479 100644
--- a/mapconfig_for_cars.xml
+++ b/mapconfig_for_cars.xml
@@ -1,20 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
- <type name="highway" id="1">
- <class name="motorway" id="101" priority="1.0" maxspeed="130" />
- <class name="motorway_link" id="102" priority="1.0" maxspeed="130" />
- <class name="motorway_junction" id="103" priority="1.0" maxspeed="130" />
- <class name="trunk" id="104" priority="1.05" maxspeed="110" />
- <class name="trunk_link" id="105" priority="1.05" maxspeed="110" />
- <class name="primary" id="106" priority="1.15" maxspeed="90" />
- <class name="primary_link" id="107" priority="1.15" maxspeed="90" />
- <class name="secondary" id="108" priority="1.5" maxspeed="90" />
- <class name="secondary_link" id="109" priority="1.5" maxspeed="90"/>
- <class name="tertiary" id="110" priority="1.75" maxspeed="90" />
- <class name="tertiary_link" id="111" priority="1.75" maxspeed="90" />
- <class name="residential" id="112" priority="2.5" maxspeed="50" />
- <class name="living_street" id="113" priority="3" maxspeed="20" />
- <class name="service" id="114" priority="2.5" maxspeed="50" />
+<configuration>
+ <tag_name name="highway" id="1">
+ <tag_value name="motorway" id="101" priority="1.0" maxspeed="130" />
+ <tag_value name="motorway_link" id="102" priority="1.0" maxspeed="130" />
+ <tag_value name="motorway_junction" id="103" priority="1.0" maxspeed="130" />
+ <tag_value name="trunk" id="104" priority="1.05" maxspeed="110" />
+ <tag_value name="trunk_link" id="105" priority="1.05" maxspeed="110" />
+ <tag_value name="primary" id="106" priority="1.15" maxspeed="90" />
+ <tag_value name="primary_link" id="107" priority="1.15" maxspeed="90" />
+ <tag_value name="secondary" id="108" priority="1.5" maxspeed="90" />
+ <tag_value name="secondary_link" id="109" priority="1.5" maxspeed="90"/>
+ <tag_value name="tertiary" id="110" priority="1.75" maxspeed="90" />
+ <tag_value name="tertiary_link" id="111" priority="1.75" maxspeed="90" />
+ <tag_value name="residential" id="112" priority="2.5" maxspeed="50" />
+ <tag_value name="living_street" id="113" priority="3" maxspeed="20" />
+ <tag_value name="service" id="114" priority="2.5" maxspeed="50" />
- <class name="unclassified" id="117" priority="3" maxspeed="90"/>
- <class name="road" id="100" priority="5" maxspeed="50" />
- </type>
+ <tag_value name="unclassified" id="117" priority="3" maxspeed="90"/>
+ <tag_value name="road" id="100" priority="5" maxspeed="50" />
+ </tag_name>
+</configuration>
diff --git a/mapconfig_for_pedestrian.xml b/mapconfig_for_pedestrian.xml
new file mode 100644
index 0000000..dac326d
--- /dev/null
+++ b/mapconfig_for_pedestrian.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+
+ <tag_name name="highway" id="1">
+ <tag_value name="footway" id="115" priority="2.5" maxspeed="5" />
+ <tag_value name="steps" id="116" priority="2.5" maxspeed="5" />
+ <tag_value name="pedestrian" id="117" priority="2.5" maxspeed="5" />
+
+ <tag_value name="unclassified" id="118" priority="3" maxspeed="9"/>
+ <tag_value name="road" id="119" priority="5" maxspeed="5" />
+ <tag_value name="path" id="120" priority="2.5" maxspeed="5" />
+ </tag_name>
+
+
+
+ <tag_name name="barrier" id="3">
+ <tag_value name="kerb" id="301" priority="1.0" maxspeed="13" />
+ <tag_value name="gate" id="302" priority="1.0" maxspeed="13" />
+ <tag_value name="bollard" id="303" priority="1.0" maxspeed="13" />
+ <tag_value name="cycle_barrier" id="304" priority="1.0" maxspeed="13" />
+ </tag_name>
+
+</configuration>
diff --git a/src/Class.cpp b/src/Class.cpp
deleted file mode 100644
index 3e95f37..0000000
--- a/src/Class.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2016 by pgRouting developers *
- * project at pgrouting.org *
- * *
- * 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 t &or 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#include <boost/lexical_cast.hpp>
-#include <string>
-
-#include "./Class.h"
-
-
-namespace osm2pgr {
-
-
-Class::Class(const char **atts) :
- m_priority(0),
- m_default_maxspeed(50) {
- auto **attribut = atts;
- while (*attribut != NULL) {
- std::string name = *attribut++;
- std::string value = *attribut++;
- if (name == "id") {
- m_id = boost::lexical_cast<int64_t>(value);
- } else if (name == "name") {
- m_name = value;
- } else if (name == "priority") {
- m_priority = boost::lexical_cast<double>(value);
- } else if (name == "maxspeed") {
- m_default_maxspeed = boost::lexical_cast<int>(value);
- } else {
- auto tag_key = boost::lexical_cast<std::string>(name);
- auto tag_value = boost::lexical_cast<std::string>(value);
- m_tags[tag_key] = tag_value;
- }
- }
-}
-
-
-
-
-
-} // end namespace osm2pgr
diff --git a/src/Configuration.h b/src/Configuration.h
deleted file mode 100644
index 721c954..0000000
--- a/src/Configuration.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2016 by pgRouting developers *
- * project at pgrouting.org *
- * *
- * 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 t &or 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-
-#ifndef SRC_CONFIGURATION_H_
-#define SRC_CONFIGURATION_H_
-
-#include <string>
-#include <map>
-#include "Type.h"
-#include "./osm_tag.h"
-#include "./Class.h"
-
-namespace osm2pgr {
-
-/**
-A configuration document.
-*/
-class Configuration {
- public:
- //! Constructor
- Configuration() = default;
-
- //! add node to the map
- void AddType(Type t);
- Type FindType(std::string typeName) const;
- Type& FindType(std::string typeName);
- Class FindClass(const Tag &tag) const;
- std::string priority_str(const Tag &tag) const;
-
-
- inline size_t has_class(const Tag &tag) const {
- return has_type(tag.key())
- && m_Types.at(tag.key()).has_class(tag.value());
- }
-
- double class_default_maxspeed(const Tag &tag) const {
- return m_Types.at(
- tag.key()).classes().at(tag.value()).default_maxspeed();
- }
-
- double class_priority(const Tag &tag) const {
- return m_Types.at(tag.key()).classes().at(tag.value()).priority();
- }
-
- const std::map<std::string, Type>& types() const {return m_Types;}
-
- inline bool has_type(const std::string &type_name) const {
- return m_Types.count(type_name) != 0;
- }
-
- private:
- //! Map, which saves the parsed types
- std::map<std::string, Type> m_Types;
-};
-
-
-} // end namespace osm2pgr
-#endif // SRC_CONFIGURATION_H_
diff --git a/src/Export2DB.cpp b/src/Export2DB.cpp
deleted file mode 100644
index e2d6e99..0000000
--- a/src/Export2DB.cpp
+++ /dev/null
@@ -1,944 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2016 by pgRouting developers *
- * project at pgrouting.org *
- * *
- * 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 t &or 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-
-#include "./Export2DB.h"
-
-#include <unistd.h>
-
-#include <iostream>
-#include <map>
-#include <string>
-#include <vector>
-
-#include "./print_progress.h"
-#include "boost/algorithm/string/replace.hpp"
-
-
-#include "./prog_options.h"
-
-namespace osm2pgr {
-
-template <typename T>
-static
-std::string
-TO_STR(const T &x) {
- return boost::lexical_cast<std::string>(x);
-}
-
-
-Export2DB::Export2DB(const po::variables_map &vm) :
- mycon(0),
- conninf("host=" + vm["host"].as<std::string>()
- + " user=" + vm["username"].as<std::string>()
- + " dbname=" + vm["dbname"].as<std::string>()
- + " port=" + vm["port"].as<std::string>()),
- tables_schema(vm["schema"].as<std::string>()),
- tables_prefix(vm["prefix"].as<std::string>()),
- tables_suffix(vm["suffix"].as<std::string>()) {
- if (!vm["password"].as<std::string>().empty())
- this->conninf+=" password=" + vm["password"].as<std::string>();
-
- create_types = std::string(
- " type_id integer PRIMARY KEY,"
- " name text");
-
- create_way_tag = std::string(
- " class_id integer PRIMARY KEY,"
- " way_id bigint");
-
- create_nodes = std::string(
- " node_id bigserial PRIMARY KEY,"
- " osm_id bigint,"
- " lon decimal(11,8),"
- " lat decimal(11,8),"
- " numOfUse int");
-
- create_vertices = std::string(
- " id bigserial PRIMARY KEY,"
- " osm_id bigint,"
- " cnt integer,"
- " chk integer,"
- " ein integer,"
- " eout integer,"
- " lon decimal(11,8),"
- " lat decimal(11,8),"
- " CONSTRAINT vertex_id UNIQUE(osm_id)");
-
- create_ways = std::string(
- " gid bigserial PRIMARY KEY,"
- " class_id integer not null,"
- " length double precision,"
- " length_m double precision,"
- " name text,"
- " source bigint,"
- " target bigint,"
- " x1 double precision,"
- " y1 double precision,"
- " x2 double precision,"
- " y2 double precision,"
- " cost double precision,"
- " reverse_cost double precision,"
- " cost_s double precision, "
- " reverse_cost_s double precision,"
- " rule text,"
- " one_way int, " // 0 unknown, 1 yes(normal direction), 2 (2 way),
- // -1 reversed (1 way but geometry is reversed)
- // 3 - reversible (one way street but direction chnges on time)
- " maxspeed_forward integer,"
- " maxspeed_backward integer,"
- " osm_id bigint,"
- " source_osm bigint,"
- " target_osm bigint,"
- " priority double precision DEFAULT 1");
-
- create_relations = std::string(
- "relation_id bigint PRIMARY KEY,"
- " type_id integer,"
- " class_id integer,"
- " name text");
-
- create_relations_ways = std::string(
- " relation_id bigint,"
- " way_id bigint,"
- " type character varying(200)");
-
- create_classes = std::string(
- " class_id integer PRIMARY KEY,"
- " type_id integer,"
- " name text,"
- " priority double precision,"
- " default_maxspeed integer");
- } // constructor
-
-Export2DB::~Export2DB() {
- PQfinish(mycon);
-}
-
-int Export2DB::connect() {
- cout << conninf << endl;
- mycon = PQconnectdb(conninf.c_str());
-
- ConnStatusType type = PQstatus(mycon);
- if (type == CONNECTION_BAD) {
- cout << "connection failed: "<< PQerrorMessage(mycon) << endl;
- return 1;
- } else {
- cout << "connection success"<< endl;
- return 0;
- }
- /***
-CONNECTION_STARTED: Waiting for connection to be made.
-CONNECTION_MADE: Connection OK; waiting to send.
-CONNECTION_AWAITING_RESPONSE: Waiting for a response from the postmaster.
-CONNECTION_AUTH_OK: Received authentication; waiting for backend start-up.
-CONNECTION_SETENV: Negotiating environment.
- ***/
-}
-
-
-/*!
-
- CREATE TEMP TABLE table (
- table_description
- );
-
-*/
-bool Export2DB::createTempTable(const std::string &table_description,
- const std::string &table) const {
- std::string sql =
- "CREATE TEMP TABLE " + table + "(" // + schema + "." + prefix etc
- + table_description + ")";
-
-
- PGresult *result = PQexec(mycon, sql.c_str());
- bool created = (PQresultStatus(result) == PGRES_COMMAND_OK);
-
- PQclear(result);
- return created;
-}
-
-/*!
-
- CREATE TABLE table (
- table_description,
- constraint
- );
-
-*/
-bool Export2DB::has_postGIS() const {
- std::string sql = "SELECT * FROM pg_extension WHERE extname = 'postgis'";
- PGresult *result = PQexec(mycon, sql.c_str());
- if (PQresultStatus(result) != PGRES_TUPLES_OK) {
- std::cout << PQresultErrorMessage(result) << "\n";
- throw;
- }
- return static_cast<bool>(PQntuples(result));
-}
-
-bool Export2DB::createTable(const std::string &table_description,
- const std::string &table,
- const std::string &constraint) const {
- std::string sql =
- "CREATE TABLE " + table + "("
- + table_description + constraint + ");";
-
- PGresult *result = PQexec(mycon, sql.c_str());
- bool created = (PQresultStatus(result) == PGRES_COMMAND_OK);
-
- std::cout << (created? "Creating '" : " Exists: '") << table <<"': OK\n";
-
- PQclear(result);
- return created;
-}
-
-
-void Export2DB::addGeometry(
- const std::string &schema, const std::string &table,
- const std::string &geometry_type) const {
- std::cout << " Adding Geometry: ";
- /** PostGIS requires the schema to be specified as separate arg if not default user's schema **/
- std::string sql =
- + " SELECT AddGeometryColumn(" + (schema == "" ? "" : "'" + schema + "' ,") + " '"
- + table + "',"
- + "'the_geom', 4326, '" + geometry_type + "',2);";
-
-
- PGresult *result = PQexec(mycon, sql.c_str());
-
- if (PQresultStatus(result) != PGRES_TUPLES_OK) {
- std::cout << PQresultErrorMessage(result) << "<-------\n";
- throw std::string(PQresultErrorMessage(result));
- }
- PQclear(result);
-}
-
-void Export2DB::addTempGeometry(
- const std::string &table,
- const std::string &geometry_type) const {
- std::string sql =
- " SELECT AddGeometryColumn('"
- + table + "',"
- + "'the_geom', 4326, '" + geometry_type + "',2);";
-
-
- PGresult *result = PQexec(mycon, sql.c_str());
- if (PQresultStatus(result) != PGRES_TUPLES_OK) {
- std::cout << PQresultErrorMessage(result);
- throw std::string(PQresultErrorMessage(result));
- }
- PQclear(result);
-}
-
-
-void Export2DB::create_gindex(const std::string &index, const std::string &table) const {
- std::string sql = (
- " CREATE INDEX "
- + index + "_gdx ON "
- + table + " using gist(the_geom);");
- PGresult *result = PQexec(mycon, sql.c_str());
-
- if (PQresultStatus(result) != PGRES_COMMAND_OK) {
- std::cout << PQresultErrorMessage(result);
- throw std::string(PQresultErrorMessage(result));
- }
- PQclear(result);
-}
-
-void Export2DB::create_idindex(const std::string &colname, const std::string &table) const {
- std::string sql = (
- " CREATE INDEX "
- " ON " + table +
- " USING btree (" + colname + ");");
- PGresult *result = PQexec(mycon, sql.c_str());
- // TODO(who) check missing
- PQclear(result);
-}
-
-// /////////////////////
-void Export2DB::createTables() const {
- auto ways_name = full_table_name("ways");
- auto vertices_name = ways_name + "_vertices_pgr";
-
- // the following are particular of the file tables
- if (createTable(create_vertices, addSchema(vertices_name))) {
- addGeometry(default_tables_schema(), vertices_name, "POINT");
- create_gindex(vertices_name, addSchema(vertices_name));
- create_idindex("osm_id", addSchema(vertices_name));
- }
-
- if (createTable(create_ways, addSchema(ways_name))) {
- addGeometry(default_tables_schema(), ways_name, "LINESTRING");
- create_gindex(ways_name, addSchema(ways_name));
- create_idindex("source_osm", addSchema(ways_name));
- create_idindex("target_osm", addSchema(ways_name));
- create_idindex("source", addSchema(ways_name));
- create_idindex("target", addSchema(ways_name));
- }
-
- createTable(create_relations_ways, addSchema(full_table_name("relations_ways")));
-
- // the following are general tables
- if (createTable(create_nodes,
- addSchema("osm_nodes"),
- ", CONSTRAINT node_id UNIQUE(osm_id)"))
- addGeometry(default_tables_schema(), "osm_nodes", "POINT");
- createTable(create_relations, addSchema("osm_relations"));
-#if 0
- createTable(create_way_tag, addSchema("osm_way_tags"));
-#endif
- createTable(create_types, addSchema("osm_way_types"));
- createTable(create_classes, addSchema("osm_way_classes"));
-}
-
-
-
-void Export2DB::dropTable(const std::string &table) const {
- std::string drop_tables("DROP TABLE IF EXISTS " + table);
- PGresult *result = PQexec(mycon, drop_tables.c_str());
- PQclear(result);
-}
-
-
-
-void Export2DB::dropTables() const {
- auto ways_name = full_table_name("ways");
- auto vertices_name = ways_name + "_vertices_pgr";
-
- dropTable(addSchema(ways_name));
- dropTable(addSchema(vertices_name));
-
- dropTable(addSchema(full_table_name("relations_ways")));
-
- // we are not deleting general tables osm_
-}
-
-/*!
-
- Inserts the data into a temporary table
- Inserts the data to the final table only if
- **osm_id**
- doesn't exist already
-
-*/
-void Export2DB::prepareExportNodes(const std::string nodes_columns) const {
- if (createTempTable(create_nodes, "__nodes_temp"))
- addTempGeometry("__nodes_temp", "POINT");
-
- std::string copy_nodes("COPY __nodes_temp (" + nodes_columns + ") FROM STDIN");
- PGresult* q_result = PQexec(mycon, copy_nodes.c_str());
- PQclear(q_result);
-}
-
-
-
-void Export2DB::exportNodes(const std::map<int64_t, Node> &nodes) const {
- std::cout << " Processing " << nodes.size() << " nodes" << ":\n";
- std::string nodes_columns(" osm_id, lon, lat, numofuse, the_geom ");
-
- prepareExportNodes(nodes_columns);
- uint32_t chunck_size = 20000;
-
-
- int64_t count = 0;
- for (auto it = nodes.begin(); it != nodes.end(); ++it) {
- auto n = *it;
-
- if ((count % (chunck_size / 100)) == 0) {
- print_progress(nodes.size(), count);
- std::cout << " Total Processed: " << count;
- }
-
- if ((++count % chunck_size) == 0) {
- PQputline(mycon, "\\.\n");
- PQendcopy(mycon);
- processSectionExportNodes(nodes_columns);
- prepareExportNodes(nodes_columns);
- }
-
- auto node = n.second;
- std::string row_data = TO_STR(node.osm_id());
- row_data += "\t";
- row_data += node.geom_str("\t");
- row_data += "\t";
- row_data += TO_STR(node.numsOfUse());
- row_data += "\t";
- row_data += node.point_geometry();
- row_data += "\n";
- PQputline(mycon, row_data.c_str());
- }
-
- print_progress(nodes.size(), count);
- PQputline(mycon, "\\.\n");
- PQendcopy(mycon);
- processSectionExportNodes(nodes_columns);
- std::cout << "\n";
-}
-
-
-void Export2DB::processSectionExportNodes(const std::string nodes_columns) const {
- std::string insert_into_nodes(
- " WITH data AS ("
- " SELECT a.* "
- " FROM __nodes_temp a LEFT JOIN " + addSchema("osm_nodes") + " b USING (osm_id) WHERE (b.osm_id IS NULL))"
-
- " INSERT INTO " + addSchema("osm_nodes") +
- "(" + nodes_columns + ") "
- " (SELECT " + nodes_columns + " FROM data); ");
- PGresult* q_result = PQexec(mycon, insert_into_nodes.c_str());
- PQclear(q_result);
- dropTable("__nodes_temp");
-}
-
-
-/*!
-
-*/
-void Export2DB::fill_vertices_table(const std::string &table, const std::string &vertices_tab) const {
- // std::cout << "Filling '" << vertices_tab << "' based on '" << table <<"'\n";
- std::string sql(
- "WITH osm_vertex AS ("
- "(select source_osm as osm_id, x1 as lon, y1 as lat FROM " + table + " where source is NULL)"
- " union "
- "(select target_osm as osm_id, x2 as lon, y2 as lat FROM " + table + " where target is NULL)"
- ") , "
- " data1 AS (SELECT osm_id, lon, lat FROM (SELECT DISTINCT * from osm_vertex) a "
- ") "
- " INSERT INTO " + vertices_tab + " (osm_id, lon, lat, the_geom) (SELECT data1.*, ST_SetSRID(ST_Point(lon, lat), 4326) FROM data1)");
-
- PGresult* q_result = PQexec(mycon, sql.c_str());
- std::cout << "Vertices inserted " << PQcmdTuples(q_result);
- PQclear(q_result);
-}
-
-
-
-
-
-void Export2DB::fill_source_target(const std::string &table, const std::string &vertices_tab) const {
- // std::cout << " Filling 'source' column of '" << table << "': ";
- std::string sql1(
- " UPDATE " + table + " AS w"
- " SET source = v.id "
- " FROM " + vertices_tab + " AS v"
- " WHERE w.source is NULL and w.source_osm = v.osm_id;");
- PGresult* q_result = PQexec(mycon, sql1.c_str());
- // std::cout << " Updated: " << PQcmdTuples(q_result) << " rows\n";
- PQclear(q_result);
-
- // std::cout << " Filling 'target' column of '" << table << "': ";
- std::string sql2(
- " UPDATE " + table + " AS w"
- " SET target = v.id "
- " FROM " + vertices_tab + " AS v"
- " WHERE w.target is NULL and w.target_osm = v.osm_id;");
- q_result = PQexec(mycon, sql2.c_str());
- // std::cout << " Updated: " << PQcmdTuples(q_result) << " rows\n";
- PQclear(q_result);
-
- // std::cout << " Filling other columns of '" << table << "': ";
- std::string sql3(
- " UPDATE " + table +
- " SET length_m = st_length(geography(ST_Transform(the_geom, 4326))),"
- " cost_s = CASE "
- " WHEN one_way = -1 THEN -st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_forward::float * 5.0 / 18.0)"
- " ELSE st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward::float * 5.0 / 18.0)"
- " END, "
- " reverse_cost_s = CASE "
- " WHEN one_way = 1 THEN -st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward::float * 5.0 / 18.0)"
- " ELSE st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward::float * 5.0 / 18.0)"
- " END "
- " WHERE length_m IS NULL;");
- q_result = PQexec(mycon, sql3.c_str());
- // std::cout << " Updated: " << PQcmdTuples(q_result) << " rows\n";
- PQclear(q_result);
-}
-
-
-void Export2DB::exportRelations(
- const std::vector<Relation> &relations,
- const Configuration &config) const {
- std::cout << " Processing " << relations.size() << " relations:";
- createTempTable(create_relations, "__relations_temp");
-
- std::string relations_columns("relation_id, type_id, class_id, name ");
- std::string copy_relations("COPY __relations_temp (" + relations_columns + ") FROM STDIN");
-
-
- PGresult* q_result = PQexec(mycon, copy_relations.c_str());
- for (auto it = relations.begin(); it != relations.end(); ++it) {
- auto relation = *it;
-
- std::string row_data = TO_STR(relation.osm_id());
- row_data += "\t";
- row_data += TO_STR(config.FindType(relation.tag_config().key()).id());
- row_data += "\t";
- row_data += TO_STR(config.FindClass(relation.tag_config()).id());
- row_data += "\t";
- row_data = row_data + relation.tag_config().key() + "=" + relation.tag_config().value();
- row_data += "\n";
- PQputline(mycon, row_data.c_str());
- }
- PQputline(mycon, "\\.\n");
- PQendcopy(mycon);
- PQclear(q_result);
- std::string insert_into_relations(
- " WITH data AS ("
- " SELECT a.* "
- " FROM __relations_temp a LEFT JOIN " + addSchema("osm_relations") + " b USING (relation_id, type_id, class_id)"
- " WHERE (b.relation_id IS NULL OR b.type_id IS NULL OR b.class_id IS NULL))"
-
- " INSERT INTO " + addSchema("osm_relations") + " "
- "(" + relations_columns + ") "
- " (SELECT " + relations_columns + " FROM data); ");
- q_result = PQexec(mycon, insert_into_relations.c_str());
- if (PQresultStatus(q_result) != PGRES_COMMAND_OK) {
- std::cerr << PQresultStatus(q_result);
- std::cerr << "Inserting to osm_relations failed \n"
- << PQerrorMessage(mycon)
- << std::endl;
- } else {
- std::cout << "\tInserted: " << PQcmdTuples(q_result) << " in " << addSchema("osm_relations") << "\n";
- }
-
- PQclear(q_result);
- dropTable("__relations_temp");
-}
-
-
-// ////////should break into 2 functions
-
-void Export2DB::exportRelationsWays(const std::vector<Relation> &relations, const Configuration &config) const {
- std::cout << " Processing way's relations: ";
- createTempTable(create_relations_ways, "__relations_ways_temp");
-
- std::string relations_ways_columns(" relation_id, way_id, type ");
- std::string copy_relations_ways("COPY __relations_ways_temp (" + relations_ways_columns + ") FROM STDIN");
- PGresult* q_result = PQexec(mycon, copy_relations_ways.c_str());
-
-
- for (auto it = relations.begin(); it != relations.end(); ++it) {
- auto relation = *it;
- for (auto it_ref = relation.way_refs().begin(); it_ref != relation.way_refs().end(); ++it_ref) {
- auto way_id = *it_ref;
- std::string row_data = TO_STR(relation.osm_id());
- row_data += "\t";
- row_data += TO_STR(way_id);
- row_data += "\t";
- row_data += TO_STR(config.FindType(relation.tag_config().key()).id());
- row_data += "\n";
- PQputline(mycon, row_data.c_str());
- }
- }
- PQputline(mycon, "\\.\n");
- PQendcopy(mycon);
- PQclear(q_result);
-
- std::string insert_into_relations_ways(
- " WITH data AS ("
- " SELECT a.* "
- " FROM __relations_ways_temp a LEFT JOIN " + addSchema(full_table_name("relations_ways")) + " b USING (relation_id, way_id)"
- " WHERE (b.relation_id IS NULL OR b.way_id IS NULL))"
-
- " INSERT INTO " + addSchema(full_table_name("relations_ways")) +
- " SELECT * FROM data; ");
- q_result = PQexec(mycon, insert_into_relations_ways.c_str());
- std::cout << "\t Inserted: " << PQcmdTuples(q_result) << " in " << addSchema(full_table_name("relations_ways")) << "\n";
- PQclear(q_result);
- dropTable("__relations_ways_temp");
-}
-
-
-
-/*
- <relation id="147411" version="5" timestamp="2010-01-22T17:02:14Z" uid="24299" user="james_hiebert" changeset="3684904">
- <member type="way" ref="25584788" role=""/>
- <member type="way" ref="35064036" role=""/>
- <member type="way" ref="35064035" role=""/>
- <member type="way" ref="35064037" role=""/>
- <member type="way" ref="35064038" role=""/>
- <member type="way" ref="35065746" role=""/>
- <member type="way" ref="48690404" role=""/>
- <member type="way" ref="24221632" role=""/>
- <tag k="name" v="Mt. Douglas Park Local Connector"/>
- <tag k="network" v="rcn"/>
- <tag k="route" v="bicycle"/>
- <tag k="type" v="route"/>
- </relation>
- */
-
-void Export2DB::exportTags(const std::map<int64_t, Way> &ways, const Configuration &config) const {
- std::cout << " Processing way's tags" << ": ";
-
- createTempTable(create_way_tag, "__way_tag_temp");
- std::string copy_way_tag("COPY __way_tag_temp (class_id, way_id) FROM STDIN");
- PGresult* q_result = PQexec(mycon, copy_way_tag.c_str());
-
- for (auto it = ways.begin(); it != ways.end(); ++it) {
- auto way = it->second;
- for (auto it_tag = way.tags().begin(); it_tag != way.tags().end(); ++it_tag) {
- auto tag = *it_tag;
- std::string row_data = TO_STR(config.FindClass(Tag(tag.first, tag.second)).id());
- row_data += "\t";
- row_data += TO_STR(way.osm_id());
- row_data += "\n";
- PQputline(mycon, row_data.c_str());
- }
- }
- PQputline(mycon, "\\.\n");
- PQendcopy(mycon);
- PQclear(q_result);
-
- std::string insert_into_tags(
- " WITH data AS ("
- " SELECT a.class_id, a.way_id "
- " FROM __way_tag_temp a LEFT JOIN " + addSchema("osm_way_tags") + " b USING (class_id, way_id) "
- " WHERE (b.class_id IS NULL OR b.way_id IS NULL))"
-
- " INSERT INTO " + addSchema("osm_way_tags") +
- " SELECT * FROM data; ");
-
- q_result = PQexec(mycon, insert_into_tags.c_str());
- std::cout << "\t Inserted: " << PQcmdTuples(q_result) << " in " << addSchema("osm_way_tags") << "\n";
- PQclear(q_result);
-
- dropTable("__way_tag_temp");
-}
-
-
-void Export2DB::prepare_table(const std::string &ways_columns) const {
- if (createTempTable(create_ways, "__ways_temp")) {
- addTempGeometry("__ways_temp", "LINESTRING");
- } else {
- std::cerr << "could not createTempTable\n";
- }
-
- std::string copy_ways("COPY __ways_temp ("
- + ways_columns
- + ") FROM STDIN");
-
- PGresult* q_result = PQexec(mycon, copy_ways.c_str());
- PQclear(q_result);
-}
-
-void Export2DB::exportWays(const std::map<int64_t, Way> &ways, const Configuration &config) const {
- std::cout << " Processing " << ways.size() << " ways" << ":\n";
-
- std::string separator("\t");
- std::string ways_columns(
- " class_id, "
- " osm_id, "
- " maxspeed_forward, maxspeed_backward, "
- " one_way, "
- " priority, "
-
- " length,"
- " x1, y1,"
- " x2, y2,"
- " source_osm,"
- " target_osm,"
- " the_geom,"
- " cost, "
- " reverse_cost,"
-
- " name ");
-
- prepare_table(ways_columns);
-
- uint32_t chunck_size = 20000;
- int64_t count = 0;
- int64_t split_count = 0;
- for (auto it = ways.begin(); it != ways.end(); ++it) {
- auto way = it->second;
-
- // std::cout << way << "\n";
- if ((count % (chunck_size / 100)) == 0) {
- print_progress(ways.size(), count);
- }
- ++count;
- if (way.tag_config().key() == "" || way.tag_config().value() == "") continue;
-
- if ((count % chunck_size) == 0) {
- PQputline(mycon, "\\.\n");
- PQendcopy(mycon);
- std::cout << " Ways Processed: " << count << "\t";
- std::cout << " Split Ways generated: " << split_count << "\t";
- process_section(ways_columns);
- split_count = 0;
- prepare_table(ways_columns);
- }
-
- // common information of the split ways
- auto way_data =
- TO_STR(config.FindClass(way.tag_config()).id()) + "\t"
- + TO_STR(way.osm_id()) + "\t"
- // maxspeed
- + way.maxspeed_forward_str() + "\t"
- + way.maxspeed_backward_str() + "\t"
- // one_way
- + way.oneWayType_str() + "\t"
- // priority
- + config.priority_str(way.tag_config()) + "\t";
-
- // name
- std::string name_data;
- if (!way.name().empty()) {
- std::string escaped_name = way.name();
- boost::replace_all(escaped_name, "\\", "");
- boost::replace_all(escaped_name, "\t", "\\\t");
- boost::replace_all(escaped_name, "\n", "");
- boost::replace_all(escaped_name, "\r", "");
- name_data = escaped_name.substr(0, 199);
- }
-
- auto splits = way.split_me();
- split_count += splits.size();
-
- for (size_t i = 0; i < splits.size(); ++i) {
- auto length = way.length_str(splits[i]);
-
- // length (degrees)
- auto split_data = length + "\t"
- // x1, y1
- + splits[i].front()->geom_str("\t") + "\t"
- // x2, y2
- + splits[i].back()->geom_str("\t") + "\t"
- // source_osm
- + TO_STR(splits[i].front()->osm_id()) + "\t"
- // target_osm
- + TO_STR(splits[i].back()->osm_id()) + "\t"
- // geometry
- + "srid=4326;" + way.geometry_str(splits[i]) + "\t";
-
- // cost based on oneway
- if (way.is_reversed())
- split_data += "-" + length;
- else
- split_data += length;
- split_data += "\t";
-
- // reverse_cost
- if (way.is_oneway())
- split_data += "-" + length;
- else
- split_data += length;
- split_data += "\t";
-
- split_data = way_data + split_data + name_data + "\n";
- PQputline(mycon, split_data.c_str());
- }
- }
- PQputline(mycon, "\\.\n");
- PQendcopy(mycon);
- std::cout << " Ways Processed: " << count << "\t";
- std::cout << " Split Ways generated: " << split_count << "\t";
- process_section(ways_columns);
-}
-
-void Export2DB::process_section(const std::string &ways_columns) const {
- auto ways_name = full_table_name("ways");
- auto vertices_name = ways_name + "_vertices_pgr";
-
- // std::cout << "Creating indices in temporary table\n";
- create_gindex("__ways_temp", "__ways_temp");
- create_idindex("source_osm", "__ways_temp");
- create_idindex("target_osm", "__ways_temp");
-
- // std::cout << "Deleting duplicated ways from temporary table\n";
- std::string delete_from_temp(
- " DELETE FROM __ways_temp a "
- " USING " + addSchema(ways_name) + " b "
- " WHERE a.the_geom ~= b.the_geom AND ST_OrderingEquals(a.the_geom, b.the_geom);");
-
- PGresult* q_result = PQexec(mycon, delete_from_temp.c_str());
- // std::cout << " Deleted " << PQcmdTuples(q_result) << " duplicated ways from temporary table\n";
- PQclear(q_result);
-
- // std::cout << "Updating to existing toplology the temporary table\n";
- fill_source_target("__ways_temp" , addSchema(vertices_name));
-
- // std::cout << "Inserting new vertices in the vertex table\n";
- fill_vertices_table("__ways_temp" , addSchema(vertices_name));
-
- // std::cout << "Updating to new toplology the temporary table\n";
- fill_source_target("__ways_temp" , addSchema(vertices_name));
-
-
- // std::cout << "Inserting new split ways to '" << addSchema(full_table_name("ways")) << "'\n";
- std::string insert_into_ways(
- " INSERT INTO " + addSchema(ways_name) +
- "(" + ways_columns + ", source, target, length_m, cost_s, reverse_cost_s) "
- " (SELECT " + ways_columns + ", source, target, length_m, cost_s, reverse_cost_s FROM __ways_temp); ");
- q_result = PQexec(mycon, insert_into_ways.c_str());
- std::cout << " Inserted " << PQcmdTuples(q_result) << " split ways\n";
- PQclear(q_result);
- dropTable("__ways_temp");
-}
-
-
-
-
-
-
-
-void Export2DB::exportTypes(const std::map<std::string, Type> &types) const {
- std::cout << " Processing " << types.size() << " way types: ";
-
- createTempTable(create_types, "__way_types_temp");
- std::string copy_types("COPY __way_types_temp (type_id, name) FROM STDIN");
-
- PGresult* q_result = PQexec(mycon, copy_types.c_str());
-
- for (auto it = types.begin(); it != types.end(); ++it) {
- auto e = *it;
- auto type = e.second;
- std::string row_data = TO_STR(type.id());
- row_data += "\t";
- row_data += type.name();
- row_data += "\n";
- PQputline(mycon, row_data.c_str());
- }
- PQputline(mycon, "\\.\n");
- PQendcopy(mycon);
- PQclear(q_result);
-
- std::string insert_into_types(
- " WITH data AS ("
- " SELECT a.* "
- " FROM __way_types_temp a LEFT JOIN " + addSchema("osm_way_types") + " b USING (type_id) "
- " WHERE (b.type_id IS NULL))"
-
- " INSERT INTO " + addSchema("osm_way_types") + " (type_id, name) "
- " (SELECT * FROM data); ");
-
- q_result = PQexec(mycon, insert_into_types.c_str());
- std::cout << "\t Inserted: " << PQcmdTuples(q_result) << " in " << addSchema("osm_way_types") << "\n";
-
- PQclear(q_result);
- dropTable("__way_types_temp");
-}
-
-
-
-
-
-
-void Export2DB::exportClasses(const std::map<std::string, Type> &types) const {
- std::cout << " Processing way's classes: ";
-
- std::string copy_classes(
- "COPY __classes_temp"
- " (class_id, type_id, name, priority, default_maxspeed)"
- " FROM STDIN");
-
- createTempTable(create_classes, "__classes_temp");
- PGresult *q_result = PQexec(mycon, copy_classes.c_str());
-
- for (auto it = types.begin(); it != types.end(); ++it) {
- auto t = *it;
- auto type(t.second);
-
- for (auto it_c = type.classes().begin(); it_c != type.classes().end(); ++it_c) {
- auto c = *it_c;
- Class clss(c.second);
- std::string row_data = TO_STR(clss.id());
- row_data += "\t";
- row_data += TO_STR(type.id());
- row_data += "\t";
- row_data += clss.name();
- row_data += "\t";
- row_data += TO_STR(clss.priority());
- row_data += "\t";
- row_data += TO_STR(clss.default_maxspeed());
- row_data += "\n";
- PQputline(mycon, row_data.c_str());
- }
- }
- PQputline(mycon, "\\.\n");
- PQendcopy(mycon);
- PQclear(q_result);
-
- std::string insert_into_classes(
- " WITH data AS ("
- " SELECT a.* "
- " FROM __classes_temp a LEFT JOIN " + addSchema("osm_way_classes") + " b USING (class_id) "
- " WHERE (b.class_id IS NULL))"
-
- " INSERT INTO " + addSchema("osm_way_classes") +
- " SELECT * FROM data; ");
-
- q_result = PQexec(mycon, insert_into_classes.c_str());
- std::cout << "\t Inserted: " << PQcmdTuples(q_result) << " in " << addSchema("osm_way_classes") << "\n";
-
- PQclear(q_result);
- dropTable("__classes_temp");
-}
-
-
-void Export2DB::createFKeys() {
- auto ways_name = full_table_name("ways");
- auto vertices_name = ways_name + "_vertices_pgr";
-
-
- std::string fk_classes(
- "ALTER TABLE " + addSchema("osm_way_classes") + " ADD FOREIGN KEY (type_id) REFERENCES " + addSchema("osm_way_types") + "(type_id)");
- PGresult *result = PQexec(mycon, fk_classes.c_str());
- if (PQresultStatus(result) != PGRES_COMMAND_OK) {
- std::cerr << PQresultStatus(result);
- std::cerr << "foreign keys for " + addSchema("osm_way_classes") + " failed:"
- << PQerrorMessage(mycon)
- << std::endl;
- PQclear(result);
- } else {
- std::cout << "Foreign keys for " + addSchema("osm_way_classes") + " table created" << std::endl;
- }
-
-
- std::string fk_relations(
- "ALTER TABLE " + addSchema(full_table_name("relations_ways")) + " ADD FOREIGN KEY (relation_id) REFERENCES " + addSchema("osm_relations") + "(relation_id); ");
- result = PQexec(mycon, fk_relations.c_str());
- if (PQresultStatus(result) != PGRES_COMMAND_OK) {
- std::cerr << PQresultStatus(result);
- std::cerr << "foreign keys for " + addSchema(full_table_name("relations_ways")) + " failed: "
- << PQerrorMessage(mycon)
- << std::endl;
- PQclear(result);
- } else {
- std::cout << "Foreign keys for " + addSchema(full_table_name("relations_ways")) + " table created" << std::endl;
- }
-
- std::string fk_ways(
- "ALTER TABLE " + addSchema(ways_name) + " ADD FOREIGN KEY (class_id) REFERENCES " + addSchema("osm_way_classes") + "(class_id);" +
- "ALTER TABLE " + addSchema(ways_name) + " ADD FOREIGN KEY (source) REFERENCES " + addSchema(vertices_name) + "(id); " +
- "ALTER TABLE " + addSchema(ways_name) + " ADD FOREIGN KEY (target) REFERENCES " + addSchema(vertices_name) + "(id);");
- result = PQexec(mycon, fk_ways.c_str());
-
- if (PQresultStatus(result) != PGRES_COMMAND_OK) {
- std::cerr << PQresultStatus(result);
- std::cerr << "foreign keys for ways failed: "
- << PQerrorMessage(mycon)
- << std::endl;
- PQclear(result);
- } else {
- std::cout << "Foreign keys for Ways table created" << std::endl;
- }
-}
-
-} // namespace osm2pgr
diff --git a/src/Export2DB.h b/src/Export2DB.h
deleted file mode 100644
index 8924542..0000000
--- a/src/Export2DB.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2016 by pgRouting developers *
- * project at pgrouting.org *
- * *
- * 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 t &or 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-
-#ifndef SRC_EXPORT2DB_H_
-#define SRC_EXPORT2DB_H_
-
-#include <libpq-fe.h>
-#include <map>
-#include <vector>
-#include <string>
-
-#include "./Node.h"
-#include "./Way.h"
-#include "./Relation.h"
-#include "./Type.h"
-#include "./Class.h"
-#include "./Configuration.h"
-#include "./prog_options.h"
-
-namespace osm2pgr {
-
-/**
- * This class connects to a postgresql database. For using this class,
- * you also need to install postgis and pgrouting
- */
-
-class Export2DB {
- public:
- /**
- * Constructor
- * @param vm variable map holding the configuration
- *
- */
- explicit Export2DB(const po::variables_map &vm);
-
- /**
- * Destructor
- * closes the connection to the database
- */
- ~Export2DB();
-
- //! connects to database
- int connect();
- bool has_postGIS() const;
-
- //! creates needed tables and geometries
- void createTables() const;
- void createTempTables() const;
- //! exports nodes to the database
- void prepareExportNodes(const std::string nodes_columns) const;
- void exportNodes(const std::map<int64_t, Node>& nodes) const;
- void processSectionExportNodes(const std::string nodes_columns) const;
-
- //! exports ways to the database
- void exportTags(
- const std::map<int64_t, Way> &ways,
- const Configuration &config) const;
- void exportRelations(
- const std::vector<Relation> &relations,
- const Configuration &config) const;
- void exportRelationsWays(
- const std::vector<Relation> &relations,
- const Configuration &config) const;
- void exportTypes(const std::map<std::string, Type>& types) const;
- void exportClasses(const std::map<std::string, Type>& types) const;
- void exportWays(
- const std::map<int64_t, Way> &ways,
- const Configuration &config) const;
-
- //! Be careful! It deletes the created tables!
- void dropTables() const;
- void dropTempTables() const;
- void createFKeys();
-
- private:
- //! to use with creating the ways
- void prepare_table(const std::string &ways_columns) const;
- void process_section(const std::string &ways_columns) const;
-
- void dropTempTable(
- const std::string &table) const;
- bool createTempTable(
- const std::string &sql,
- const std::string &table) const;
- void dropTable(const std::string &table) const;
- bool createTempTable(
- const std::string &sql,
- const std::string &table);
- bool createTable(
- const std::string &sql,
- const std::string &table,
- const std::string &constraint = std::string("")) const;
- void addTempGeometry(
- const std::string &table,
- const std::string &geometry_type) const;
- void addGeometry(
- const std::string &schema,
- const std::string &table,
- const std::string &geometry_type) const;
- void create_gindex(
- const std::string &index,
- const std::string &table) const;
- void create_idindex(
- const std::string &colname,
- const std::string &table) const;
- inline std::string full_table_name(const std::string &table) const {
- return tables_prefix + table + tables_suffix;
- }
- inline std::string addSchema(const std::string &table) const {
- return (default_tables_schema() == "" ? ""
- : default_tables_schema() + ".") + table;
- }
- inline std::string default_tables_schema() const {
- return tables_schema;
- }
- void fill_vertices_table(
- const std::string &table,
- const std::string &vertices_tab) const;
- void fill_source_target(
- const std::string &table,
- const std::string &vertices_tab) const;
-
- private:
- PGconn *mycon;
- std::string conninf;
- std::string tables_schema;
- std::string tables_prefix;
- std::string tables_suffix;
-
- // create table query constants
- std::string create_classes;
- std::string create_nodes;
- std::string create_ways;
- std::string create_relations;
- std::string create_relations_ways;
- std::string create_way_tag;
- std::string create_types;
- std::string create_vertices;
-};
-} // namespace osm2pgr
-
-#endif // SRC_EXPORT2DB_H_
diff --git a/src/OSMDocument.cpp b/src/OSMDocument.cpp
deleted file mode 100644
index 0a62313..0000000
--- a/src/OSMDocument.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2016 by pgRouting developers *
- * project at pgrouting.org *
- * *
- * 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 t &or 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-
-#include <boost/lexical_cast.hpp>
-#include <vector>
-#include <map>
-#include <utility>
-#include <string>
-#include <iostream>
-#include "./OSMDocument.h"
-#include "./Configuration.h"
-#include "./Node.h"
-#include "./Relation.h"
-#include "./Way.h"
-
-namespace osm2pgr {
-
-OSMDocument::OSMDocument(const Configuration &config, size_t lines) :
- m_nodesErrs(0),
- m_rConfig(config),
- m_lines(lines) {
-}
-
-
-void OSMDocument::AddNode(Node n) {
- m_Nodes[n.osm_id()] = n;
-}
-
-void OSMDocument::AddWay(Way w) {
- m_Ways[w.osm_id()] = w;
-}
-
-void OSMDocument::AddRelation(const Relation &r) {
- m_Relations.push_back(r);
-}
-
-Node*
-OSMDocument::FindNode(int64_t nodeRefId) {
- auto it = m_Nodes.find(nodeRefId);
- return &(it->second);
-}
-
-bool
-OSMDocument::has_node(int64_t nodeRefId) const {
- auto it = m_Nodes.find(nodeRefId);
- return (it != m_Nodes.end());
-}
-
-Way*
-OSMDocument::FindWay(int64_t way_id) {
- auto it = m_Ways.find(way_id);
- return &(it->second);
-}
-
-bool
-OSMDocument::has_way(int64_t way_id) const {
- auto it = m_Ways.find(way_id);
- return (it != m_Ways.end());
-}
-
-void
-OSMDocument::add_node(Way &way, const char **atts) {
- auto **attribut = atts;
- std::string key = *attribut++;
- std::string value = *attribut++;
- auto node_id = (key == "ref")? boost::lexical_cast<int64_t>(value): -1;
- if (!has_node(node_id)) {
- ++m_nodesErrs;
- } else {
- auto node = FindNode(node_id);
- node->incrementUse();
- way.add_node(node);
- }
-}
-
-void
-OSMDocument::add_config(Way &way, const Tag &tag) const {
- auto k = tag.key();
- auto v = tag.value();
- /*
- * for example
- * <tag highway=motorway> // k = highway v = motorway
- * <tag highway=path> // k = highway v = motorway
- *
- * And the configuration file has:
- * <type name="highway" id="1">
- * <class name="motorway" id="101" priority="1.0" maxspeed="130" />
- * // there is no class name="path"
- */
- if (m_rConfig.has_class(tag)) {
- if ((way.tag_config().key() == "" && way.tag_config().value() == "")
- || (
- m_rConfig.has_class(tag)
- && m_rConfig.has_class(way.tag_config())
- && m_rConfig.class_priority(tag)
- < m_rConfig.class_priority(way.tag_config())
- )
- ) {
- way.tag_config(tag);
-#if 0
- if (m_rConfig.has_class(way.tag_config())) {
- way.add_tag(tag);
-
- auto newValue = m_rConfig.class_default_maxspeed(way.tag_config());
- if (way.maxspeed_forward() <= 0) {
- way.maxspeed_forward(newValue);
- }
- if (way.maxspeed_backward() <= 0) {
- way.maxspeed_backward(newValue);
- }
- }
-#endif
- }
- }
-}
-
-
-} // namespace osm2pgr
diff --git a/src/OSMDocument.h b/src/OSMDocument.h
deleted file mode 100644
index 4e38b3f..0000000
--- a/src/OSMDocument.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2016 by pgRouting developers *
- * project at pgrouting.org *
- * *
- * 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 t &or 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-
-#ifndef SRC_OSMDOCUMENT_H_
-#define SRC_OSMDOCUMENT_H_
-
-#include <map>
-#include <vector>
-#include <string>
-#include "./Configuration.h"
-
-namespace osm2pgr {
-
-
-class Node;
-class Way;
-class Relation;
-
-/**
- An osm-document.
-*/
-class OSMDocument {
- public:
- //! Constructor
- OSMDocument(const Configuration& config, size_t lines);
-
- inline size_t lines() const {return m_lines;}
- inline bool has_class(const Tag &tag) const {
- return m_rConfig.has_class(tag);
- }
- inline double class_priority(const Tag &tag) const {
- return m_rConfig.class_priority(tag);
- }
- inline double class_default_maxspeed(const Tag &tag) const {
- return m_rConfig.class_default_maxspeed(tag);
- }
-
- const std::map<int64_t, Node>& nodes() const {return m_Nodes;}
- const std::map<int64_t, Way>& ways() const {return m_Ways;}
- const std::vector<Relation>& relations() const {return m_Relations;}
-
- //! add node to the map
- void AddNode(Node n);
-
- //! add way to the map
- void AddWay(Way w);
-
- //! find node by using an ID
- bool has_node(int64_t nodeRefId) const;
- Node* FindNode(int64_t nodeRefId);
-
- bool has_way(int64_t way_id) const;
- Way* FindWay(int64_t way_id);
-
- void AddRelation(const Relation &r);
-
- void add_node(Way &way, const char **atts);
- size_t nodesErrs() {return m_nodesErrs;}
-
- /**
- * add the configuration tag used for the speeds
- */
- void add_config(Way &way, const Tag &tag) const;
-
- private:
- // ! parsed nodes
- std::map<int64_t, Node> m_Nodes;
- //! parsed ways
- std::map<int64_t, Way> m_Ways;
- //! parsed relations
- std::vector<Relation> m_Relations;
-
-
- size_t m_nodesErrs;
- public:
- const Configuration& m_rConfig;
- private:
- size_t m_lines;
-};
-
-} // end namespace osm2pgr
-#endif // SRC_OSMDOCUMENT_H_
diff --git a/src/configuration/configuration.cpp b/src/configuration/configuration.cpp
new file mode 100644
index 0000000..5019353
--- /dev/null
+++ b/src/configuration/configuration.cpp
@@ -0,0 +1,93 @@
+/***************************************************************************
+ * Copyright (C) 2016 by pgRouting developers *
+ * project at pgrouting.org *
+ * *
+ * 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 t &or 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+
+#include "configuration/configuration.h"
+#include <boost/lexical_cast.hpp>
+#include <iostream>
+#include <string>
+
+namespace osm2pgr {
+
+void Configuration::add_tag_key(const Tag_key &t_key) {
+ if (has_tag_key(t_key.name())) {
+ std::cerr << "Duplicate Tag_key found in condfiguration file"
+ << t_key.name() << " .... sikipping\n";
+ return;
+ }
+ m_Tag_keys[t_key.name()] = t_key;
+}
+
+
+bool
+Configuration::has_tag_key(const std::string &key) const {
+ return m_Tag_keys.count(key) != 0;
+}
+
+
+bool
+Configuration::has_tag(const Tag &tag) const {
+ return has_tag_key(tag.key())
+ && tag_key(tag).has_tag_value(tag);
+}
+
+
+const Tag_value&
+Configuration::tag_value(const Tag &tag) const {
+ return tag_key(tag).tag_value(tag);
+}
+
+
+const Tag_key&
+Configuration::tag_key(const Tag &tag) const {
+ return m_Tag_keys.at(tag.key());
+}
+
+
+double
+Configuration::maxspeed(const Tag &tag) const {
+ if (tag_key(tag).has(tag, "maxspeed"))
+ return boost::lexical_cast<double>(tag_key(tag).get(tag, "maxspeed"));
+ return 50;
+}
+
+double
+Configuration::maxspeed_forward(const Tag &tag) const {
+ if (tag_key(tag).has(tag, "maxspeed:backward"))
+ return boost::lexical_cast<double>(tag_key(tag).get(tag, "maxspeed:backward"));
+ return maxspeed(tag);
+}
+
+double
+Configuration::maxspeed_backward(const Tag &tag) const {
+ if (tag_key(tag).has(tag, "maxspeed:forward"))
+ return boost::lexical_cast<double>(tag_key(tag).get(tag, "maxspeed:backward"));
+ return maxspeed(tag);
+}
+
+double
+Configuration::priority(const Tag &tag) const {
+ if (tag_key(tag).has(tag, "priority"))
+ return boost::lexical_cast<double>(tag_key(tag).get(tag, "priority"));
+ return 0;
+}
+
+
+} // end namespace osm2pgr
diff --git a/src/Type.cpp b/src/configuration/tag_key.cpp
similarity index 53%
rename from src/Type.cpp
rename to src/configuration/tag_key.cpp
index 3786144..240a399 100644
--- a/src/Type.cpp
+++ b/src/configuration/tag_key.cpp
@@ -18,39 +18,67 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#include "configuration/tag_key.h"
+#include "utilities/utilities.h"
#include <boost/lexical_cast.hpp>
#include <string>
#include <map>
-#include "./Class.h"
-#include "./Type.h"
namespace osm2pgr {
-void Type::AddClass(const Class &pClass) {
- m_Classes[pClass.name()] = pClass;
+
+Tag_key::Tag_key(const char **atts)
+ : Element(atts) {
}
+void
+Tag_key::add_tag_value(const Tag_value &value) {
+ m_Tag_values[value.name()] = value;
+}
-Type::Type(const char **atts) {
- auto **attribut = atts;
- while (*attribut != NULL) {
- std::string name = *attribut++;
- std::string value = *attribut++;
- if (name == "id") {
- m_id = boost::lexical_cast<int64_t>(value);
- } else if (name == "name") {
- m_name = value;
- } else {
- auto tag_key = boost::lexical_cast<std::string>(name);
- auto tag_value = boost::lexical_cast<std::string>(value);
- m_tags[tag_key] = tag_value;
- }
- }
+bool
+Tag_key::has_tag_value(const Tag &tag) const {
+ return m_Tag_values.count(tag.value());
}
-void
-Type::add_class(const char **atts) {
- AddClass(Class(atts));
+const
+Tag_value&
+Tag_key::tag_value(
+ const Tag &tag) const {
+ return m_Tag_values.at(tag.value());
+}
+
+bool
+Tag_key::has(const Tag &tag, const std::string &str) const {
+ return tag_value(tag).has_attribute(str)
+ || this->has_attribute(str);
+}
+
+std::string
+Tag_key::get(const Tag &tag, const std::string &str) const {
+ assert(this->has(tag, str));
+ return (tag_value(tag).has_attribute(str)) ?
+ tag_value(tag).get(str)
+ : this->get_attribute(str);
+}
+
+
+std::vector<std::string>
+Tag_key::values(const std::vector<std::string> &columns) const {
+ std::vector<std::string> export_values;
+
+ for (const auto &item : m_Tag_values) {
+ auto row = item.second.values(columns, true);
+ row[1] = name();
+ row[2] = item.second.get_attribute("name");
+ // row[3] has priority
+ if (row[4] == "") row[4] = "40"; // max_speed
+ if (row[5] == "") row[5] = row[4];
+ if (row[6] == "") row[6] = row[4];
+ if (row[7] == "") row[7] = "N";
+ export_values.push_back(tab_separated(row));
+ }
+ return export_values;
}
diff --git a/src/Configuration.cpp b/src/configuration/tag_value.cpp
similarity index 68%
rename from src/Configuration.cpp
rename to src/configuration/tag_value.cpp
index fd711bb..3dc94a2 100644
--- a/src/Configuration.cpp
+++ b/src/configuration/tag_value.cpp
@@ -18,41 +18,48 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
-
-#include "./Configuration.h"
+#include "configuration/tag_value.h"
#include <boost/lexical_cast.hpp>
-#include <iostream>
#include <string>
-#include "./osm_tag.h"
-#include "./Type.h"
-#include "./Class.h"
+#include <cassert>
+
namespace osm2pgr {
-void Configuration::AddType(Type t) {
- if (has_type(t.name())) {
- std::cerr << "duplicate Type found in condfiguration file"
- << t.name() << "\n";
- return;
- }
- m_Types[t.name()] = t;
+Tag_value::Tag_value(const char **atts) :
+ Element(atts){
+ assert(has_attribute("name"));
}
-Type& Configuration::FindType(std::string name) {
- return m_Types.at(name);
+std::string
+Tag_value::get(const std::string &str) const {
+ assert(has_attribute(str));
+ return get_attribute(str);
}
-Type Configuration::FindType(std::string name) const {
- return m_Types.at(name);
+
+#if 0
+std::string
+Tag_value::priority() const {
+ assert(has_attribute("priority"));
+ return get_attribute("priority");
}
-Class Configuration::FindClass(const Tag &tag) const {
- return m_Types.at(tag.key()).classes()[tag.value()];
+std::string
+Tag_value::maxspeed() const {
+ assert(has_attribute("maxspeed"));
+ return get_attribute("maxspeed");
}
+#endif
-std::string Configuration::priority_str(const Tag &tag) const {
- return boost::lexical_cast<std::string>(FindClass(tag).priority());
+std::string
+Tag_value::name() const {
+ assert(has_attribute("name"));
+ return get_attribute("name");
}
+
+
+
} // end namespace osm2pgr
diff --git a/src/database/Export2DB.cpp b/src/database/Export2DB.cpp
new file mode 100644
index 0000000..6df5313
--- /dev/null
+++ b/src/database/Export2DB.cpp
@@ -0,0 +1,700 @@
+/***************************************************************************
+ * Copyright (C) 2016 by pgRouting developers *
+ * project at pgrouting.org *
+ * *
+ * 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 t &or 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+
+#include "database/Export2DB.h"
+#include "database/table_management.h"
+
+#include <unistd.h>
+
+#include <iostream>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "utilities/print_progress.h"
+#include "utilities/prog_options.h"
+#include "utilities/utilities.h"
+
+#include "boost/algorithm/string/replace.hpp"
+
+
+namespace osm2pgr {
+
+template <typename T>
+static
+std::string
+TO_STR(const T &x) {
+ return boost::lexical_cast<std::string>(x);
+}
+
+
+Export2DB::Export2DB(const po::variables_map &vm, const std::string &connection) :
+ m_vm(vm),
+ conninf(connection),
+ m_tables(vm)
+{
+}
+
+Export2DB::~Export2DB() {
+#if 0
+ PQfinish(mycon);
+#endif
+}
+
+int Export2DB::connect() {
+ try {
+ pqxx::connection db_conn(conninf);
+ pqxx::work Xaction(db_conn);
+ cout << "connection success"<< endl;
+ return 0;
+
+ } catch (const std::exception &e) {
+ cerr << e.what() << std::endl;
+ return 1;
+ }
+}
+
+
+bool
+Export2DB::has_extension(const std::string &name) const {
+ try {
+ pqxx::connection db_conn(conninf);
+ pqxx::work Xaction(db_conn);
+ std::string sql = "SELECT * FROM pg_extension WHERE extname = '" + name + "'";
+ auto result = Xaction.exec(sql);
+ return result.size() == 1;
+
+ } catch (const std::exception &e) {
+ cerr << e.what() << std::endl;
+ return false;
+ }
+}
+
+
+#ifndef NDEBUG
+bool
+Export2DB::install_postGIS() const {
+ try {
+ pqxx::connection db_conn(conninf);
+ pqxx::work Xaction(db_conn);
+ Xaction.exec("CREATE EXTENSION postgis");
+ Xaction.exec("CREATE EXTENSION hstore");
+ Xaction.commit();
+ return true;
+ } catch (const std::exception &e) {
+ // cerr << e.what() << std::endl;
+ }
+ return false;
+}
+#endif
+
+
+
+
+// /////////////////////
+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";
+
+ Xaction.exec(ways().create());
+ std::cout << "TABLE: " << ways().addSchema() << " created ... OK.\n";
+
+ Xaction.exec(pois().create());
+ std::cout << "TABLE: " << pois().addSchema() << " created ... OK.\n";
+
+ Xaction.exec(configuration().create());
+ std::cout << "TABLE: " << configuration().addSchema() << " created ... OK.\n";
+
+ Xaction.commit();
+ } catch (const std::exception &e) {
+ std::cerr << "\n" << e.what() << std::endl;
+ std::cerr << "FATAL ERROR: could not routing tables" << std::endl;
+ exit(1);
+ }
+
+ 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";
+
+ 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";
+
+ 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;
+ }
+}
+
+
+
+
+void Export2DB::dropTables() const {
+ try {
+ pqxx::connection db_conn(conninf);
+ pqxx::work Xaction(db_conn);
+
+ Xaction.exec(ways().drop());
+ std::cout << "TABLE: " << ways().addSchema() << " droped ... OK.\n";
+
+ Xaction.exec(vertices().drop());
+ std::cout << "TABLE: " << vertices().addSchema() << " droped ... OK.\n";
+
+ Xaction.exec(pois().drop());
+ std::cout << "TABLE: " << pois().addSchema() << " droped ... OK.\n";
+
+ Xaction.exec(configuration().drop());
+ std::cout << "TABLE: " << configuration().addSchema() << " droped ... OK.\n";
+
+ Xaction.commit();
+ } catch (const std::exception &e) {
+ cerr << e.what() << std::endl;
+ cerr << "ROLLBACK applied";
+ }
+
+ try {
+ pqxx::connection db_conn(conninf);
+ pqxx::work Xaction(db_conn);
+ Xaction.exec(osm_nodes().drop());
+ std::cout << "TABLE: " << osm_nodes().addSchema() << " droped ... OK.\n";
+
+ Xaction.exec(osm_ways().drop());
+ std::cout << "TABLE: " << osm_ways().addSchema() << " droped ... OK.\n";
+
+ Xaction.exec(osm_relations().drop());
+ std::cout << "TABLE: " << osm_relations().addSchema() << " droped ... OK.\n";
+
+ Xaction.commit();
+ } catch (const std::exception &e) {
+ cerr << e.what() << std::endl;
+ }
+}
+
+
+void
+Export2DB::export_configuration(const std::map<std::string, Tag_key>& items) const {
+
+ auto osm_table = m_tables.get_table("configuration");
+
+ std::vector<std::string> values;
+
+ for (const auto &item : items) {
+ auto row = item.second.values(osm_table.columns());
+ values.insert(values.end(), row.begin(), row.end());
+ }
+
+ export_osm(values, osm_table);
+}
+
+
+void
+Export2DB::export_osm(
+ const std::vector<std::string> &values,
+ const Table &table) const {
+ if (values.empty()) return;
+
+ auto columns = table.columns();
+ std::string temp_table(table.temp_name());
+ auto create_sql = table.tmp_create();
+ std::string copy_sql( "COPY " + temp_table + " (" + comma_separated(columns) + ") FROM STDIN");
+
+#if 0
+ std::cout << "\n" << create_sql;
+ std::cout << "\n" << copy_sql;
+
+#endif
+
+ size_t count = 0;
+ try {
+
+
+ pqxx::connection db_con(conninf);
+ pqxx::work Xaction(db_con);
+ PGconn *mycon = PQconnectdb(conninf.c_str());
+
+ PGresult *res = PQexec(mycon, create_sql.c_str());
+ res = PQexec(mycon, copy_sql.c_str());
+ if (res) {};
+
+ for (auto it = values.begin(); it != values.end(); ++it) {
+ auto str = *it;
+
+ ++count;
+
+ PQputline(mycon, str.c_str());
+ }
+
+ PQputline(mycon, "\\.\n");
+
+ if (PQendcopy(mycon) != 0) {
+ Xaction.exec("DROP TABLE " + temp_table);
+ PQfinish(mycon);
+ Xaction.commit();
+
+ if (values.size() < 2) {
+ for (const auto &v : values) {
+ std::cout << "\n*****ERROR HERE:\n" << v << "\n******";
+ }
+ return;
+ }
+ size_t inc = values.size() / 2;
+ export_osm(std::vector<std::string>(values.begin(), values.begin() + inc), table);
+ export_osm(std::vector<std::string>(values.begin() + inc , values.end()), table);
+ return;
+ };
+
+ PQfinish(mycon);
+ Xaction.exec(m_tables.post_process(table));
+ Xaction.exec("DROP TABLE " + temp_table);
+ Xaction.commit();
+ } catch (const std::exception &e) {
+ std::cerr << "\n" << e.what() << std::endl;
+ std::cerr << "While exporting to " << table.addSchema() << " TODO insert one by one skip the guilty one\n";
+ }
+}
+
+
+
+
+/*!
+
+*/
+void Export2DB::fill_vertices_table(
+ const std::string &table,
+ const std::string &vertices_tab,
+ pqxx::work &Xaction) const {
+ // std::cout << "Filling '" << vertices_tab << "' based on '" << table <<"'\n";
+ std::string sql(
+ "WITH osm_vertex AS ("
+ "(SELECT source_osm AS osm_id, x1 AS lon, y1 AS lat FROM " + table + " where source IS NULL)"
+ " union "
+ "(SELECT target_osm AS osm_id, x2 AS lon, y2 AS lat FROM " + table + " where target IS NULL)"
+ ") , "
+ " data1 AS (SELECT osm_id, lon, lat FROM (SELECT DISTINCT * FROM osm_vertex) a "
+ ") "
+ " INSERT INTO " + vertices_tab + " (osm_id, lon, lat, the_geom) (SELECT data1.*, ST_SetSRID(ST_Point(lon, lat), 4326) FROM data1)");
+ auto result = Xaction.exec(sql);
+
+ std::cout << "\t Vertices inserted: " << result.affected_rows();
+}
+
+
+
+
+
+void Export2DB::fill_source_target(
+ const std::string &table,
+ const std::string &vertices_tab,
+ pqxx::work &Xaction) const {
+ // std::cout << " Filling 'source' column of '" << table << "':'" << vertices_tab << "'\n";
+ std::string sql1(
+ " UPDATE " + table + " AS w"
+ " SET source = v.id "
+ " FROM " + vertices_tab + " AS v"
+ " WHERE w.source IS NULL and w.source_osm = v.osm_id;");
+ Xaction.exec(sql1);
+
+ std::string sql2(
+ " UPDATE " + table + " AS w"
+ " SET target = v.id "
+ " FROM " + vertices_tab + " AS v"
+ " WHERE w.target IS NULL and w.target_osm = v.osm_id;");
+ Xaction.exec(sql2);
+
+ std::string sql3(
+ " UPDATE " + table +
+ " SET length_m = ST_length(geography(ST_Transform(the_geom, 4326))),"
+ " coST_s = CASE "
+ " WHEN one_way = -1 THEN -ST_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_forward::float * 5.0 / 18.0)"
+ " ELSE ST_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward::float * 5.0 / 18.0)"
+ " END, "
+ " reverse_cost_s = CASE "
+ " WHEN one_way = 1 THEN -ST_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward::float * 5.0 / 18.0)"
+ " ELSE ST_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward::float * 5.0 / 18.0)"
+ " END "
+ " WHERE length_m IS NULL;");
+ Xaction.exec(sql3);
+}
+
+
+
+
+void Export2DB::exportWays(const Ways &ways, const Configuration &config) const {
+ std::cout << " Processing " << ways.size() << " ways" << ":\n";
+
+ Table table = this->ways();
+
+ auto columns = table.columns();
+ auto ways_columns = comma_separated(columns);
+
+ size_t chunck_size = m_vm["chunk"].as<size_t>();
+
+ auto create_sql = table.tmp_create();
+ auto temp_table(table.temp_name());
+
+ std::string copy_sql( "COPY " + temp_table + " (" + comma_separated(columns) + ") FROM STDIN");
+
+
+ int64_t split_count = 0;
+ int64_t count = 0;
+ size_t start = 0;
+ auto it = ways.begin();
+
+ while (start < ways.size()) {
+ auto limit = (start + chunck_size) < ways.size() ? start + chunck_size : ways.size();
+ try {
+ pqxx::connection db_con(conninf);
+ pqxx::work Xaction(db_con);
+
+ PGconn *mycon = PQconnectdb(conninf.c_str());
+ PGresult *res = PQexec(mycon, create_sql.c_str());
+ res = PQexec(mycon, copy_sql.c_str());
+ if (res) {};
+
+
+ for (auto i = start; i < limit; ++i) {
+ auto way = *it;
+
+ ++count;
+ ++it;
+
+ if (way.tag_config().key() == "" || way.tag_config().value() == "") continue;
+
+ std::vector<std::string> common_values;
+ common_values.push_back(TO_STR(config.tag_value(way.tag_config()).id()));
+ common_values.push_back(TO_STR(way.osm_id()));
+ common_values.push_back(way.maxspeed_forward_str() == "-1" ? TO_STR(config.maxspeed_forward(way.tag_config())) : way.maxspeed_forward_str()) ;
+ common_values.push_back(way.maxspeed_backward_str() == "-1" ? TO_STR(config.maxspeed_backward(way.tag_config())) : way.maxspeed_backward_str()) ;
+ common_values.push_back(way.oneWayType_str());
+ common_values.push_back(way.oneWay());
+ // common_values.push_back(way.has_attribute("oneway") ? way.get_attribute("oneway") : std::string(""));
+ common_values.push_back(TO_STR(config.priority(way.tag_config())));
+
+ auto splits = way.split_me();
+ split_count += splits.size();
+ for (size_t j = 0; j < splits.size(); ++j) {
+ auto length = way.length_str(splits[j]);
+
+ auto values = common_values;
+ values.push_back(length);
+ values.push_back(splits[j].front()->lon());
+ values.push_back(splits[j].front()->lat());
+ values.push_back(splits[j].back()->lon());
+ values.push_back(splits[j].back()->lat());
+ values.push_back(TO_STR(splits[j].front()->osm_id()));
+ values.push_back(TO_STR(splits[j].back()->osm_id()));
+ values.push_back(way.geometry_str(splits[j]));
+
+ // cost based on oneway
+ if (way.is_reversed())
+ values.push_back(std::string("-") + length);
+ else
+ values.push_back(length);
+
+ // reverse_cost
+ if (way.is_oneway())
+ values.push_back(std::string("-") + length);
+ else
+ values.push_back(length);
+
+ values.push_back(way.name());
+ PQputline(mycon, tab_separated(values).c_str());
+ }
+ }
+
+ PQputline(mycon, "\\.\n");
+ PQendcopy(mycon);
+
+ print_progress(ways.size(), count);
+ process_section(ways_columns, Xaction);
+ Xaction.exec("DROP TABLE " + temp_table);
+ Xaction.commit();
+ } catch (const std::exception &e) {
+ std::cerr << "\n" << e.what() << std::endl;
+ std::cerr << "While processing FROM " << start << "th \t to: " << limit << "th way\n";
+ std::cerr << "count" << count << " While processing FROM " << start << "th \t to: " << limit << "th way\n";
+ }
+
+ start = limit;
+ }
+}
+
+
+
+void Export2DB::process_section(const std::string &ways_columns, pqxx::work &Xaction) const {
+ // std::cout << "Creating indices in temporary table\n";
+ auto temp_table(ways().temp_name());
+
+ Xaction.exec("CREATE INDEX "+ temp_table + "_gdx ON "+ temp_table + " using gist(the_geom);");
+ Xaction.exec("CREATE INDEX ON "+ temp_table + " USING btree (source_osm)");
+ Xaction.exec("CREATE INDEX ON "+ temp_table + " USING btree (target_osm)");
+
+
+
+
+ // std::cout << "Deleting duplicated ways FROM temporary table\n";
+ std::string delete_from_temp(
+ " DELETE FROM "+ temp_table + " a "
+ " USING " + ways().addSchema() + " b "
+ " WHERE a.the_geom ~= b.the_geom AND ST_OrderingEquals(a.the_geom, b.the_geom);");
+ Xaction.exec(delete_from_temp);
+
+ // std::cout << "Updating to existing toplology the temporary table\n";
+ fill_source_target(temp_table, vertices().addSchema(), Xaction);
+
+ // std::cout << "Inserting new vertices in the vertex table\n";
+ fill_vertices_table(temp_table, vertices().addSchema(), Xaction);
+
+ // std::cout << "Updating to new toplology the temporary table\n";
+ fill_source_target(temp_table, vertices().addSchema(), Xaction);
+
+
+ // std::cout << "Inserting new split ways to '" << addSchema(full_table_name("ways")) << "'\n";
+ std::string insert_into_ways(
+ " INSERT INTO " + ways().addSchema() +
+ "(" + ways_columns + ", source, target, length_m, cost_s, reverse_cost_s) "
+ " (SELECT " + ways_columns + ", source, target, length_m, cost_s, reverse_cost_s FROM " + temp_table + "); ");
+ auto result = Xaction.exec(insert_into_ways);
+ std::cout << "\tSplit ways inserted " << result.affected_rows() << "\n";
+}
+
+
+
+
+
+int64_t
+Export2DB::get_val(const std::string sql) const {
+#if 0
+ std::cout << "\nExecuting: \n" << sql << "\n";
+#endif
+ try {
+ pqxx::connection db_conn(conninf);
+ pqxx::work Xaction(db_conn);
+ auto result = Xaction.exec(sql);
+ Xaction.commit();
+ if (result.size() == 0) return 0;
+ return result[0][0].as<int64_t>();
+ } catch (const std::exception &e) {
+ std::cout << "\nWARNING: " << e.what() << std::endl;
+ std::cout << sql << "\n";
+ }
+ return 0;
+}
+
+void
+Export2DB::execute(const std::string sql) const {
+#if 0
+ std::cout << "\nExecuting: \n" << sql << "\n";
+#endif
+ try {
+ pqxx::connection db_conn(conninf);
+ pqxx::work Xaction(db_conn);
+ Xaction.exec(sql);
+ Xaction.commit();
+ } catch (const std::exception &e) {
+ std::cout << "\nWARNING: " << e.what() << std::endl;
+ std::cout << sql << "\n";
+ }
+}
+
+
+
+/*
+ *
+ * Integrity of the OSM data IS not ensured so failings are ignored
+ *
+ * Due to the fact that indexes slow down the process, no index IS created
+ *
+ * After all the data IS inserted then its time to create indices & foreign keys
+ *
+ */
+void Export2DB::createFKeys() const {
+
+ /*
+ * configuration:
+ */
+ execute(configuration().primary_key("id"));
+ execute(configuration().unique("tag_id"));
+
+ /*
+ * vertices
+ */
+ execute(vertices().primary_key("id"));
+ execute(vertices().unique("osm_id"));
+ execute(vertices().gist_index());
+
+ /*
+ * Ways
+ */
+ execute(ways().primary_key("gid"));
+ execute(ways().foreign_key("source", vertices(), "id"));
+ execute(ways().foreign_key("target", vertices(), "id"));
+ execute(ways().foreign_key("source_osm", vertices(), "osm_id"));
+ execute(ways().foreign_key("target_osm", vertices(), "osm_id"));
+ execute(ways().foreign_key("tag_id", configuration(), "tag_id"));
+ execute(ways().gist_index());
+
+ /*
+ * ponitsOfInterest
+ */
+ execute(pois().primary_key("pid"));
+ execute(pois().gist_index());
+ execute(pois().unique("osm_id"));
+}
+
+void Export2DB::process_pois() const {
+ if (!m_vm.count("addnodes")) return;
+
+ std::cout << "\nAdding functions for processing Points of Interest ..." << endl;
+ /* osm2pgr_pois_update_part_of_topology */
+ execute(pois().sql(0));
+
+
+ /* osm2pgr_pois_update_not_part_of_topology */
+ execute(pois().sql(1));
+
+
+ /* osm2pgr_pois_find_side */
+ execute(pois().sql(2));
+
+
+ /* osm2pgr_pois_new_geom */
+ execute(pois().sql(3));
+
+
+ /* osm2pgr_pois_update */
+ execute(pois().sql(4));
+
+ std::cout << "\nTo process pointsOfInterest table:"
+ "\nosm2pgr_pois_update(radius deault 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;
+#if 0
+ std::string array;
+ int64_t total = 0;
+ auto limit = get_val(
+ "SELECT count(*) FROM " + pois().addSchema()
+ + "\n WHERE vertex_id IS NULL AND edge_id IS NULL");
+
+
+ std::cout << "\nFinding closest edge to " << limit << " Points Of Interest\n";
+ for (int64_t i = 0; i < limit; ++i) {
+ auto curr_tot = get_val(
+ "SELECT osm2pgr_pois_update_not_part_of_topology(200, 50, ARRAY[" + array + "]::BIGINT[])");
+ total += curr_tot;
+
+ if (curr_tot == 0) {
+ auto pid_outOfRange = get_val(" SELECT pid FROM " + pois().addSchema()
+ +"\n WHERE vertex_id IS NULL AND edge_id IS NULL"
+ +"\n AND pid not in (SELECT unnest(ARRAY[" + array +"]::BIGINT[]))"
+ +"\n limit 1;");
+ if (pid_outOfRange == 0) break;
+ if (array.empty()) {
+ array += boost::lexical_cast<std::string>(pid_outOfRange);
+ } else {
+ array += "," + boost::lexical_cast<std::string>(pid_outOfRange);
+ }
+
+ if (get_val(
+ +"SELECT count(*) FROM (SELECT * FROM " + pois().addSchema()
+ +"\n WHERE vertex_id IS NULL AND edge_id IS NULL"
+ +"\n AND pid not in (SELECT unnest(ARRAY[" + array +"]::BIGINT[]))) AS a"
+ ) == 0) break;
+ }
+
+ print_progress(limit, total);
+ }
+
+ if (!array.empty()) {
+ std::cout << "\nNo edge found within distance (200 + 50)mts on pid(s): " << array << "\n";
+ }
+
+ execute("SELECT osm2pgr_pois_find_side()");
+ execute("SELECT osm2pgr_pois_new_geom()");
+ execute(
+ "\n WITH "
+ "\n base AS ("
+ "\n SELECT pid, w.id AS wid, w.the_geom AS wgeom, p.the_geom AS pgeom"
+ "\n FROM " + pois().addSchema() + " AS p JOIN " + ways().addSchema() + " AS w ON (edge_id = w.id)"
+ + "\n WHERE edge_id IS not NULL"
+ + "\n ),"
+
+ + "\n foo AS ("
+ + "\n SELECT wid, ST_dumppoints(wgeom) AS dp"
+ + "\n FROM base"
+ + "\n ),"
+
+ + "\n blade AS ("
+ + "\n SELECT wid, ST_collect((dp).geom) AS blade"
+ + "\n FROM foo"
+ + "\n GROUP BY wid"
+ + "\n ),"
+
+ + "\n split AS ("
+ + "\n SELECT base.*, (ST_Dump(ST_split(wgeom, blade))).geom AS line"
+ + "\n FROM blade JOIN base"
+ + "\n USING (wid)"
+ + "\n ),"
+
+ + "\n distance AS ("
+ + "\n SELECT split.*, ST_distance(line, pgeom) AS dist FROM split"
+ + "\n ),"
+
+ + "\n second AS ("
+ + "\n SELECT pid, min(dist) FROM distance GROUP BY pid"
+ + "\n ), "
+
+ + "\n last AS ("
+ + "\n SELECT pid,"
+ + "\n (ST_y(ST_startpoint(line)) - ST_y(ST_endpoint(line))) * ST_x(pgeom)"
+ + "\n + (ST_x(ST_endpoint(line)) - ST_x(ST_startpoint(line))) * ST_y(pgeom)"
+ + "\n + (ST_x(ST_startpoint(line)) * ST_y(ST_endpoint(line)) - ST_x(ST_endpoint(line))"
+ + "\n * ST_y(ST_startpoint(line))) AS val"
+ + "\n FROM distance join second using (pid) where dist = min"
+ + "\n )"
+
+ + "\n UPDATE " + pois().addSchema() + " set side = case when val>0 then 'L' when val<0 then 'R' else 'B' end "
+ + "\n FROM last "
+ + "\n WHERE last.pid = " + pois().addSchema() + ".pid;"
+
+ );
+#endif
+}
+
+} // namespace osm2pgr
diff --git a/src/database/configuration_config.cpp b/src/database/configuration_config.cpp
new file mode 100644
index 0000000..0c8e70f
--- /dev/null
+++ b/src/database/configuration_config.cpp
@@ -0,0 +1,81 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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*/
+
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE configuration
+ */
+
+
+Table
+Tables::configuration_config() const {
+ Table table(
+ /* name */
+ "configuration",
+
+ /* schema */
+ m_vm["schema"].as<std::string>(),
+
+ /* full name */
+ "configuration",
+
+ /* standard column creation string */
+ std::string(
+ " id serial"
+ ", tag_id INTEGER"
+ ", tag_key TEXT"
+ ", tag_value TEXT"
+ ", priority double precision"
+ ", maxspeed double precision"
+ ", maxspeed_forward double precision"
+ ", maxspeed_backward double precision"
+ ", force char"),
+
+ /* other columns */
+ "",
+
+ /* geometry */
+ "");
+
+
+
+ std::vector<std::string> columns;
+ columns.push_back("tag_id");
+ columns.push_back("tag_key");
+ columns.push_back("tag_value");
+ columns.push_back("priority");
+ columns.push_back("maxspeed");
+ columns.push_back("maxspeed_forward");
+ columns.push_back("maxspeed_backward");
+ columns.push_back("force");
+
+ table.set_columns(columns);
+
+ return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/database/osm_nodes_config.cpp b/src/database/osm_nodes_config.cpp
new file mode 100644
index 0000000..d02a62b
--- /dev/null
+++ b/src/database/osm_nodes_config.cpp
@@ -0,0 +1,82 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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*/
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE osm_nodes
+ */
+
+
+Table
+Tables::osm_nodes_config() const {
+ Table table(
+ /* name */
+ std::string("osm_nodes"),
+
+ /* schema */
+ m_vm["schema"].as<std::string>(),
+
+ /* full name */
+ "osm_nodes",
+
+ /* standard column creation string */
+ std::string(
+ " osm_id bigint PRIMARY KEY"
+ + (m_vm.count("attributes") ?
+ (std::string(", attributes hstore"))
+ : "")
+ + (m_vm.count("tags") ?
+ (std::string(", tags hstore"))
+#if 0
+ (std::string(", tags ") + (m_vm.count("hstore") ? "hstore" : "json"))
+#endif
+ : "")),
+
+ /* other columns */
+ // TODO get from the configuration maybe this task is to be done on the configuration*/
+ ", tag_name TEXT"
+ ", tag_value TEXT"
+ ", name TEXT ",
+ // end todo
+
+ /* geometry */
+ "POINT");
+ std::vector<std::string> columns;
+ columns.push_back("osm_id");
+ columns.push_back("the_geom");
+ // TODO get from the configuration
+ columns.push_back("tag_name");
+ columns.push_back("tag_value");
+ columns.push_back("name");
+ // end todo
+ if (m_vm.count("attributes")) columns.push_back("attributes");
+ if (m_vm.count("tags")) columns.push_back("tags");
+ table.set_columns(columns);
+
+ return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/database/osm_relations_config.cpp b/src/database/osm_relations_config.cpp
new file mode 100644
index 0000000..0e82378
--- /dev/null
+++ b/src/database/osm_relations_config.cpp
@@ -0,0 +1,83 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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*/
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE osm_relations
+ */
+
+
+Table
+Tables::osm_relations_config() const {
+ Table table(
+ /* name */
+ "osm_relations",
+
+ /* schema */
+ m_vm["schema"].as<std::string>(),
+
+ /* full name */
+ "osm_relations",
+
+ /* standard column creation string */
+ std::string(
+ " osm_id bigint PRIMARY KEY"
+ " , members hstore"
+ + (m_vm.count("attributes") ?
+ (std::string(", attributes hstore"))
+ : "")
+ + (m_vm.count("tags") ?
+ (std::string(", tags hstore"))
+ : "")
+ ),
+ /* other columns */
+ // TODO get from the configuration maybe this task is to be done on the configuration*/
+ ", tag_name TEXT"
+ ", tag_value TEXT"
+ ", name TEXT ",
+ // end todo
+
+ /* geometry */
+ "");
+
+
+ std::vector<std::string> columns;
+ columns.push_back("osm_id");
+ columns.push_back("members");
+ // TODO get from the configuration
+ columns.push_back("tag_name");
+ columns.push_back("tag_value");
+ columns.push_back("name");
+ // end todo
+ if (m_vm.count("attributes")) columns.push_back("attributes");
+ if (m_vm.count("tags")) columns.push_back("tags");
+
+ table.set_columns(columns);
+
+ return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/database/osm_ways_config.cpp b/src/database/osm_ways_config.cpp
new file mode 100644
index 0000000..b52e742
--- /dev/null
+++ b/src/database/osm_ways_config.cpp
@@ -0,0 +1,88 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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*/
+
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+#include <vector>
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE osm_ways
+ */
+
+
+Table
+Tables::osm_ways_config() const {
+ Table table(
+ /* name */
+ "osm_ways",
+
+ /* schema */
+ m_vm["schema"].as<std::string>(),
+
+ /* full name */
+ "osm_ways",
+
+ /* standard column creation string */
+ std::string(
+ " osm_id bigint PRIMARY KEY"
+ " , members hstore"
+ + (m_vm.count("attributes") ?
+ (std::string(", attributes hstore"))
+ : "")
+ + (m_vm.count("tags") ?
+ (std::string(", tags hstore"))
+#if 0
+ (std::string(", tags ") + (m_vm.count("hstore") ? "hstore" : "json"))
+#endif
+ : "")),
+
+ /* other columns */
+ /* TODO get from the configuration maybe this task is to be done on the configuration*/
+ std::string(
+ ", tag_name TEXT"
+ ", tag_value TEXT"
+ ", name TEXT "),
+ // end todo
+
+ /* geometry */
+ "LINESTRING");
+
+
+ std::vector<std::string> columns;
+ columns.push_back("osm_id");
+ columns.push_back("members");
+ // TODO get from the configuration
+ columns.push_back("tag_name");
+ columns.push_back("tag_value");
+ columns.push_back("name");
+ // end todo
+ if (m_vm.count("attributes")) columns.push_back("attributes");
+ if (m_vm.count("tags")) columns.push_back("tags");
+ columns.push_back("the_geom");
+
+ table.set_columns(columns);
+
+ return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/database/pois_config.cpp b/src/database/pois_config.cpp
new file mode 100644
index 0000000..65b6653
--- /dev/null
+++ b/src/database/pois_config.cpp
@@ -0,0 +1,89 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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*/
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE osm_nodes
+ */
+
+
+Table
+Tables::pois_config() const {
+ Table table(
+ /* name */
+ std::string("pointsofinterest"),
+
+ /* schema */
+ m_vm["schema"].as<std::string>(),
+
+ /* full name */
+ std::string(
+ m_vm["prefix"].as<std::string>()
+ + "pointsofinterest"
+ + m_vm["suffix"].as<std::string>()),
+
+
+ /* standard column creation string */
+ std::string(
+ " pid bigserial"
+ ", osm_id bigint"
+ ", vertex_id bigint"
+ ", edge_id bigint"
+ ", side CHAR"
+ ", fraction FLOAT"
+ ", length_m FLOAT"
+ + (m_vm.count("attributes") ?
+ (std::string(", attributes hstore"))
+ : "")
+ + (m_vm.count("tags") ?
+ (std::string(", tags hstore"))
+ : "")),
+
+ /* other columns */
+ std::string(
+ ", tag_name TEXT"
+ ", tag_value TEXT"
+ ", name TEXT "),
+ // end todo
+
+ /* geometry */
+ "POINT");
+ std::vector<std::string> columns;
+ columns.push_back("osm_id");
+ columns.push_back("the_geom");
+ // TODO get from the configuration
+ columns.push_back("tag_name");
+ columns.push_back("tag_value");
+ columns.push_back("name");
+ // end todo
+ if (m_vm.count("attributes")) columns.push_back("attributes");
+ if (m_vm.count("tags")) columns.push_back("tags");
+ table.set_columns(columns);
+
+ return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/database/table_management.cpp b/src/database/table_management.cpp
new file mode 100644
index 0000000..b30b636
--- /dev/null
+++ b/src/database/table_management.cpp
@@ -0,0 +1,444 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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*/
+
+
+#include <unistd.h>
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+
+namespace osm2pgr {
+
+Table::Table(
+ const std::string &name,
+ const std::string &schema,
+ const std::string &full_name,
+
+ const std::string &create_str,
+ const std::string &other_columns,
+ const std::string &geometry
+ ):
+ m_name(name),
+ m_schema(schema),
+ m_full_name(full_name),
+
+ m_create(create_str),
+ m_other_columns(other_columns),
+ m_geometry(geometry)
+ { }
+
+std::string
+Table::gist_index() const {
+ return "CREATE INDEX ON " + addSchema()
+ + "\n USING GIST (the_geom);";
+}
+
+
+std::string
+Table::foreign_key(
+ const std::string &column,
+ const Table &table,
+ const std::string &table_column) const {
+ return "ALTER TABLE " + addSchema()
+ + "\n ADD FOREIGN KEY (" + column + ")"
+ + "\n REFERENCES " + table.addSchema() + "(" + table_column + ")"
+ + "\n ON UPDATE NO ACTION \n ON DELETE NO ACTION;";
+}
+
+
+std::string
+Table::unique(const std::string &column) const {
+ return std::string("ALTER TABLE " + addSchema()
+ + "\n ADD UNIQUE (" + column + ")");
+}
+
+std::string
+Table::primary_key(const std::string &column) const {
+ return std::string("ALTER TABLE " + addSchema()
+ + "\n ADD PRIMARY KEY (" + column + ")");
+}
+
+
+
+void
+Table::set_columns(const std::vector<std::string> &columns) {
+ m_columns = columns;
+}
+
+std::string
+Table::addSchema() const {
+ return
+ m_schema
+ + (m_schema == "" ? "" : ".")
+ + m_full_name;
+}
+
+
+
+/*
+ * sql strings
+ */
+
+std::string
+Table::create() const {
+ std::string sql =
+ "CREATE TABLE " + addSchema() + " ("
+ + m_create
+ + m_other_columns
+ + m_constraint + ")";
+
+ sql += " WITH (autovacuum_enabled = false);";
+
+ if (m_geometry != "") {
+ sql += "SELECT AddGeometryColumn('"
+ + m_schema
+ + (m_schema == "" ? "" : "', '")
+ + table_name() + "', 'the_geom', 4326, '" + m_geometry + "', 2);";
+
+ if (name() == "pointsofinterest") {
+ sql += "SELECT AddGeometryColumn('"
+ + m_schema
+ + (m_schema == "" ? "" : "', '")
+ + table_name() + "', 'new_geom', 4326, '" + m_geometry + "', 2);";
+ }
+ }
+
+
+ return sql;
+}
+
+
+std::string
+Table::drop() const {
+ return "DROP TABLE IF EXISTS " + addSchema() + ";";
+}
+
+
+std::string
+Table::temp_name() const {
+ return
+ "__"
+ + table_name()
+ + boost::lexical_cast<std::string>(getpid());
+}
+
+
+std::string
+Table::tmp_create() const {
+ std::string sql =
+ "CREATE UNLOGGED TABLE "
+ + temp_name()
+ + " ("
+ + m_create
+ + m_other_columns
+ + ");";
+ if (m_geometry != "") {
+ sql += "SELECT AddGeometryColumn('"
+ + temp_name() + "', 'the_geom', 4326, '" + m_geometry + "', 2);";
+ }
+ return sql;
+}
+
+
+std::string
+Tables::post_process(const Table &table) const {
+ if (table.name() == "osm_nodes"
+ || table.name() == "pointsofinterest"
+ || table.name() == "osm_ways"
+ || table.name() == "osm_relations") {
+ std::string str(
+ " WITH data AS ("
+ " SELECT a.* "
+ " FROM " + table.temp_name() + " a LEFT JOIN " + table.addSchema() + " b USING (osm_id) WHERE (b.osm_id IS NULL))"
+
+ + " INSERT INTO " + table.addSchema()
+ + "(" + comma_separated(table.columns()) + ") "
+ + " (SELECT " + comma_separated(table.columns()) + " FROM data); ");
+ return str;
+ } else if (table.name() == "configuration") {
+
+ std::string str(
+ " WITH data AS ("
+ " SELECT a.* "
+ " FROM " + configuration().temp_name() + " a LEFT JOIN " + configuration().addSchema() + " b USING (tag_id) WHERE (b.tag_id IS NULL))"
+
+ + " INSERT INTO " + configuration().addSchema()
+ + "(" + comma_separated(configuration().columns()) + ") "
+ + " (SELECT " + comma_separated(configuration().columns()) + " FROM data); ");
+ return str;
+ }
+ return "";
+}
+
+
+
+Tables::Tables(const po::variables_map &vm) :
+ m_vm(vm),
+ /*
+ * initializing tables
+ */
+ m_ways(ways_config()),
+ m_ways_vertices_pgr(ways_vertices_pgr_config()),
+ m_points_of_interest(pois_config()),
+ m_configuration(configuration_config()),
+
+ m_osm_nodes(osm_nodes_config()),
+ m_osm_ways(osm_ways_config()),
+ m_osm_relations(osm_relations_config())
+{
+ m_points_of_interest.add_sql(
+ "\nCREATE OR REPLACE FUNCTION osm2pgr_pois_update_part_of_topology()"
+ "\nRETURNS BIGINT AS"
+ "\n$$"
+ "\n-----------------------------------------------------------------"
+ "\n-- When the point of interest is part of the routing topology"
+ "\n-- Sets the vid value to the corresponding id of the vertices table"
+ "\n-- The distance from the routing topólogy to the point of Interest is 0"
+ "\n-----------------------------------------------------------------\n"
+ "\nDECLARE"
+ "\n curr_tot BIGINT;"
+ "\nBEGIN"
+ "\n UPDATE " + pois().addSchema() + " AS pois"
+ + "\n SET (vertex_id, length_m) = (vertices.id, 0)"
+ + "\n FROM " + vertices().addSchema() + " AS vertices"
+ + "\n WHERE vertex_id IS NULL AND pois.osm_id = vertices.osm_id;"
+ + "\n GET DIAGNOSTICS curr_tot = ROW_COUNT;"
+ + "\n RETURN curr_tot;"
+ + "\nEND;"
+ + "\n$$"
+ + "\nLANGUAGE plpgsql;"
+ + "\nCOMMENT ON FUNCTION 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[])"
+ "\n RETURNS BIGINT AS"
+ "\n $$"
+ "\n-----------------------------------------------------------------"
+ "\n-- When A point of interest is NOT part of the routing topology"
+ "\n-- Looks for a POI that has not being assigned a vid or an edge_id"
+ "\n-- - grabs all the POIS that are within the (radius) mts distance of the POI"
+ "\n-- - grabs all the edges that are within the (radius + within)mts of the POI"
+ "\n-- - FOR each POI in POIS"
+ "\n-- - For closest edge to the POI:"
+ "\n-- - if the closest point in the edge to the POI is the an ending vertex:"
+ "\n-- - Sets the vid value to the corresponding id of the vertices table"
+ "\n-- - if the closest point in the edge to the POI is NOT an ending vertex:"
+ "\n-- - Sets the edge_id and the fraction values"
+ "\n-----------------------------------------------------------------"
+ "\n DECLARE"
+ "\n curr_tot BIGINT;"
+ "\n BEGIN"
+ "\n WITH "
+ "\n poi AS ("
+ "\n SELECT ST_buffer(the_geom::geography, $1)::geometry AS bufferPois,"
+ "\n ST_buffer(the_geom::geography, $1 + $2)::geometry AS bufferWays"
+ "\n FROM " + pois().addSchema()
+ +"\n WHERE vertex_id IS NULL AND edge_id IS NULL"
+ +"\n AND pid not in (SELECT unnest(tooFar))"
+ +"\n limit 1"
+ +"\n ),"
+ +"\n pois AS ("
+ +"\n SELECT * FROM " + pois().addSchema() + ", poi"
+ +"\n WHERE ST_Within(the_geom, bufferPois) "
+ +"\n AND vertex_id IS NULL AND edge_id IS NULL"
+ +"\n AND pid not in (SELECT unnest(tooFar))"
+ +"\n ),"
+ +"\n wayss AS ("
+ +"\n SELECT * FROM " + ways().addSchema() + ", poi"
+ +"\n WHERE ST_Intersects(the_geom, bufferWays)"
+ +"\n ),"
+ +"\n first AS ("
+ +"\n SELECT ways.gid AS wid,"
+ +"\n source_osm, target_osm,"
+ +"\n ST_distance(pois.the_geom::geography, ways.the_geom::geography) AS dist,"
+ +"\n pois.osm_id AS vid,"
+ +"\n ST_linelocatepoint(ways.the_geom, pois.the_geom) AS fraction"
+ +"\n FROM wayss AS ways , pois"
+ +"\n WHERE pois.vertex_id IS NULL AND pois.edge_id IS NULL"
+ +"\n ),"
+
+ +"\n second AS ("
+ +"\n SELECT vid, min(dist) FROM first group by vid"
+ +"\n ),"
+
+
+ +"\n third AS ("
+ +"\n SELECT first.vid, NULL::bigint AS wid, NULL::FLOAT AS fraction, first.dist, source_osm AS v_osm_id FROM first, second WHERE dist = min AND fraction in (0)"
+ +"\n UNION "
+ +"\n SELECT first.vid, NULL::bigint AS wid, NULL::FLOAT AS fraction, first.dist, target_osm AS v_osm_id FROM first, second WHERE dist = min AND fraction in (1)"
+ +"\n ),"
+ +"\n last AS ("
+ +"\n SELECT third.*, b.id FROM third join " + vertices().addSchema() + " AS b ON (third.v_osm_id = b.osm_id)"
+ +"\n UNION"
+ +"\n SELECT first.vid, first.wid, first.fraction, first.dist, NULL AS v_osm_id, NULL::bigint AS id FROM first, second WHERE dist = min AND fraction not in (0, 1)"
+ +"\n )"
+
+ +"\n UPDATE " + pois().addSchema() +" AS pois SET (vertex_id, edge_id, fraction, length_m) = (last.id, last.wid, last.fraction, last.dist)"
+ +"\n FROM last WHERE pois.osm_id = last.vid;"
+ +"\n GET DIAGNOSTICS curr_tot = ROW_COUNT;"
+ +"\n return curr_tot;"
+ +"\n END;"
+ +"\n $$"
+ +"\n LANGUAGE plpgsql;"
+ +"\nCOMMENT ON FUNCTION 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()"
+ "\n RETURNS VOID AS"
+ "\n $$"
+ "\n WITH "
+ "\n base AS ("
+ "\n SELECT pid, w.gid AS wid, w.the_geom AS wgeom, p.the_geom AS pgeom"
+ "\n FROM " + pois().addSchema() + " AS p JOIN " + ways().addSchema() + " AS w ON (edge_id = w.gid)"
+ + "\n WHERE edge_id IS NOT NULL AND side IS NULL"
+ + "\n ),"
+
+ + "\n foo AS ("
+ + "\n SELECT wid, ST_dumppoints(wgeom) AS dp"
+ + "\n FROM base"
+ + "\n ),"
+
+ + "\n blade AS ("
+ + "\n SELECT wid, ST_collect((dp).geom) AS blade"
+ + "\n FROM foo"
+ + "\n GROUP BY wid"
+ + "\n ),"
+
+ + "\n split AS ("
+ + "\n SELECT base.*, (ST_Dump(ST_split(wgeom, blade))).geom AS line"
+ + "\n FROM blade JOIN base"
+ + "\n USING (wid)"
+ + "\n ),"
+
+ + "\n distance AS ("
+ + "\n SELECT split.*, ST_distance(line, pgeom) AS dist FROM split"
+ + "\n ),"
+
+ + "\n second AS ("
+ + "\n SELECT pid, min(dist) FROM distance GROUP BY pid"
+ + "\n ), "
+
+ + "\n last AS ("
+ + "\n SELECT pid,"
+ + "\n (ST_y(ST_startpoint(line)) - ST_y(ST_endpoint(line))) * ST_x(pgeom)"
+ + "\n + (ST_x(ST_endpoint(line)) - ST_x(ST_startpoint(line))) * ST_y(pgeom)"
+ + "\n + (ST_x(ST_startpoint(line)) * ST_y(ST_endpoint(line)) - ST_x(ST_endpoint(line))"
+ + "\n * ST_y(ST_startpoint(line))) AS val"
+ + "\n FROM distance join second using (pid) where dist = min"
+ + "\n )"
+
+ + "\n UPDATE " + pois().addSchema() + " set side = case when val>0 then 'L' when val<0 then 'R' else 'B' end "
+ + "\n FROM last "
+ + "\n WHERE last.pid = " + pois().addSchema() + ".pid;"
+ +"\n $$"
+ +"\n LANGUAGE sql;"
+ +"\nCOMMENT ON FUNCTION osm2pgr_pois_find_side()"
+ + "\n IS 'osm2pgrouting generated function';"
+ );
+
+ m_points_of_interest.add_sql(
+ "CREATE OR REPLACE FUNCTION osm2pgr_pois_new_geom()"
+ "\n RETURNS VOID AS"
+ "\n $$"
+ "\n UPDATE " + pois().addSchema()
+ + "\n SET new_geom = ST_LineInterpolatePoint(e.the_geom, fraction)"
+ + "\n FROM " + ways().addSchema() + " AS e WHERE edge_id = gid;"
+
+ "\n UPDATE " + pois().addSchema()
+ + "\n SET new_geom = the_geom"
+ + "\n WHERE vertex_id IS NOT NULL;"
+ + "\n $$"
+ + "\n LANGUAGE sql;"
+ +"\nCOMMENT ON FUNCTION 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)"
+
+ "\n RETURNS BIGINT AS"
+ "\n $$"
+ "\n-----------------------------------------------------------------"
+ "\n-- Cycles thru all the POIS to either:"
+ "\n-- Sets the vid value to the corresponding id of the vertices table"
+ "\n-- Set the edge_id & disance"
+ "\n-- Sets the side"
+ "\n-- "
+ "\n-- By working on areas of (radius)mts on POIS"
+ "\n-- looking on edges that are at least (within) mts of each POI"
+ "\n-- POIS that do not have a closest edge is considered as tooFar"
+ "\n-- "
+ "\n-- TooFar: are the POIS that do not have a closest edge within (radius + within)mts"
+ "\n-- Recommended values radius = 200, within 50 mts"
+ "\n-----------------------------------------------------------------\n"
+ "\n DECLARE"
+ "\n curr_tot BIGINT;"
+ "\n total BIGINT :=0;"
+ "\n rec RECORD;"
+ "\n factor FLOAT = 0.5;"
+ "\n tooFar BIGINT[];"
+ "\n BEGIN"
+ "\n total = 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);"
+
+ +" 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()
+ +"\n WHERE vertex_id IS NULL AND edge_id IS NULL"
+ +"\n AND pid not in (SELECT unnest(tooFar))"
+ +"\n limit 1 INTO rec;"
+ +"\n raise notice 'Not within range: pid = %', rec.pid;"
+ +"\n tooFar := tooFar || rec.pid;"
+ +"\n SELECT count(*) FROM (SELECT * FROM " + pois().addSchema()
+ +"\n WHERE vertex_id IS NULL AND edge_id IS NULL"
+ +"\n AND pid not in (SELECT unnest(tooFar)) LIMIT 1) a INTO rec;"
+
+ +"\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 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';"
+ );
+
+
+}
+
+
+} // namespace osm2pgr
diff --git a/src/database/ways_config.cpp b/src/database/ways_config.cpp
new file mode 100644
index 0000000..7b21871
--- /dev/null
+++ b/src/database/ways_config.cpp
@@ -0,0 +1,130 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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*/
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+#include <string>
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE osm_nodes
+ */
+
+
+Table
+Tables::ways_config() const {
+ Table table(
+ /* name */
+ "ways",
+
+ /* schema */
+ m_vm["schema"].as<std::string>(),
+
+ /* full name */
+ std::string(
+ m_vm["prefix"].as<std::string>()
+ + "ways"
+ + m_vm["suffix"].as<std::string>()),
+
+ /* standard column creation string */
+ std::string(
+ " gid bigserial"
+ ", osm_id bigint"
+ ", tag_id integer"
+
+ ", length double precision"
+ ", length_m double precision"
+ ", name text"
+ ", source bigint"
+ ", target bigint"
+ ", source_osm bigint"
+ ", target_osm bigint"
+
+ ", cost double precision"
+ ", reverse_cost double precision"
+ ", cost_s double precision "
+ ", reverse_cost_s double precision"
+ ", rule text"
+ ", one_way int "
+ ", oneway TEXT "
+
+ ", x1 double precision"
+ ", y1 double precision"
+ ", x2 double precision"
+ ", y2 double precision"
+
+ ", maxspeed_forward double precision"
+ ", maxspeed_backward double precision"
+ ", priority double precision DEFAULT 1"
+#if 0
+ + (m_vm.count("attributes") ?
+ (std::string(", attributes ") + (m_vm.count("hstore") ? "hstore" : "json"))
+ : "")
+ + (m_vm.count("tags") ?
+ (std::string(", tags ") + (m_vm.count("hstore") ? "hstore" : "json"))
+ : "")
+#endif
+ ),
+
+ /* other columns */
+ "",
+
+ /* geometry */
+ "LINESTRING");
+
+
+ std::vector<std::string> columns;
+ columns.push_back("tag_id");
+ columns.push_back("osm_id");
+ columns.push_back("maxspeed_forward");
+ columns.push_back("maxspeed_backward");
+ columns.push_back("one_way");
+ columns.push_back("oneway");
+ columns.push_back("priority");
+
+ columns.push_back("length");
+ columns.push_back("x1"); columns.push_back("y1");
+ columns.push_back("x2"); columns.push_back("y2");
+ columns.push_back("source_osm");
+ columns.push_back("target_osm");
+ columns.push_back("the_geom");
+ columns.push_back("cost");
+ columns.push_back("reverse_cost");
+ columns.push_back("name");
+
+
+#if 0
+ // TODO get from the configuration
+ columns.push_back("tag_name");
+ columns.push_back("tag_value");
+
+ // end todo
+ if (m_vm.count("attributes")) columns.push_back("attributes");
+ if (m_vm.count("tags")) columns.push_back("tags");
+#endif
+ table.set_columns(columns);
+
+ return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/database/ways_vertices_pgr_config.cpp b/src/database/ways_vertices_pgr_config.cpp
new file mode 100644
index 0000000..315ebb0
--- /dev/null
+++ b/src/database/ways_vertices_pgr_config.cpp
@@ -0,0 +1,79 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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*/
+
+#include "boost/lexical_cast.hpp"
+#include "database/table_management.h"
+#include "utilities/utilities.h"
+#include <string>
+
+namespace osm2pgr {
+
+
+/*
+ * configuring TABLE osm_nodes
+ */
+
+
+Table
+Tables::ways_vertices_pgr_config() const {
+ Table table(
+ /* name */
+ "ways_vertices_pgr",
+
+ /* schema */
+ m_vm["schema"].as<std::string>(),
+
+ /* full name */
+ std::string(
+ m_vm["prefix"].as<std::string>()
+ + "ways"
+ + m_vm["suffix"].as<std::string>()
+ + "_vertices_pgr"),
+
+ /* standard column creation string */
+ std::string(
+ " id bigserial"
+ ", osm_id bigint"
+ ", eout integer"
+ ", lon decimal(11,8)"
+ ", lat decimal(11,8)"
+ ", cnt integer"
+ ", chk integer"
+ ", ein integer"
+#if 0
+ + (m_vm.count("attributes") ?
+ (std::string(", attributes ") + (m_vm.count("hstore") ? "hstore" : "json"))
+ : "")
+ + (m_vm.count("tags") ?
+ (std::string(", tags ") + (m_vm.count("hstore") ? "hstore" : "json"))
+ : "")
+#endif
+ ),
+
+ /* other columns */
+ "",
+
+ /* geometry */
+ "POINT");
+
+ return table;
+}
+
+
+} //namespace osm2pgr
diff --git a/src/osm_element.cpp b/src/osm_element.cpp
deleted file mode 100644
index 1b61c26..0000000
--- a/src/osm_element.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2016 by pgRouting developers *
- * project at pgrouting.org *
- * *
- * 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 t &or 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-
-#include <boost/lexical_cast.hpp>
-#include <map>
-#include <string>
-#include "./osm_tag.h"
-#include "./osm_element.h"
-
-namespace osm2pgr {
-
-
-Element::Element(const char **atts) :
- m_visible(true) {
- auto **attribut = atts;
- while (*attribut != NULL) {
- std::string name = *attribut++;
- std::string value = *attribut++;
- if (name == "id") {
- m_osm_id = boost::lexical_cast<int64_t>(value);
- }
- if (name == "visible") {
- m_visible = (value == "true")? true : false;
- }
- m_attributes[name] = value;
- }
- }
-
-Tag
- Element::add_tag(const Tag &tag) {
- m_tags[tag.key()] = tag.value();
- return tag;
- }
-
-bool
- Element::has_tag(const std::string& key) const {
- return m_tags.find(key) != m_tags.end();
- }
-
-std::string
- Element::get_tag(const std::string& key) const {
- return m_tags.find(key)->second;
- }
-
-bool
- Element::has_attribute(const std::string& key) const {
- return m_attributes.find(key) != m_attributes.end();
- }
-
-std::string
- Element::get_attribute(const std::string& key) const {
- return m_attributes.find(key)->second;
- }
-
-std::string Element::attributes_str() const {
- if (m_tags.empty()) return "\"\"";
- std::string str("\"");
- for (auto it = m_attributes.begin(); it != m_attributes.end(); ++it) {
- auto attribute = *it;
- str += attribute.first + "=>" + attribute.second + ",";
- }
-#if 0
- str.pop_back();
- str += "\"";
-#else
- str[str.size()-1] = '\"';
-#endif
- return str;
-}
-
-std::string Element::tags_str() const {
- if (m_tags.empty()) return "";
- std::string str("\"");
- for (auto it = m_tags.begin(); it != m_tags.end(); ++it) {
- auto tag = *it;
- str += tag.first + "=>" + tag.second + ",";
- }
-#if 0
- str.pop_back();
- str += "\"";
-#else
- str[str.size()-1] = '\"';
-#endif
- return str;
-}
-
-} // namespace osm2pgr
diff --git a/src/Node.cpp b/src/osm_elements/Node.cpp
similarity index 82%
rename from src/Node.cpp
rename to src/osm_elements/Node.cpp
index d24ba4e..2a6a0d8 100644
--- a/src/Node.cpp
+++ b/src/osm_elements/Node.cpp
@@ -28,8 +28,8 @@
#include <map>
#include <cassert>
#include <math.h>
-#include "./osm_tag.h"
-#include "./Node.h"
+#include "osm_elements/osm_tag.h"
+#include "osm_elements/Node.h"
namespace osm2pgr {
@@ -41,14 +41,21 @@ Node::Node(const char **atts) :
assert(has_attribute("lon"));
}
+void
+Node::tag_config(const Tag &tag) {
+ Element::tag_config(tag);
+ ++m_numsOfUse;
+ ++m_numsOfUse;
+}
+
double
Node::getLength(const Node &previous) const {
- auto y1 = boost::lexical_cast<double>(get_attribute("lat"));
- auto x1 = boost::lexical_cast<double>(get_attribute("lon"));
- auto y2 = boost::lexical_cast<double>(previous.get_attribute("lat"));
- auto x2 = boost::lexical_cast<double>(previous.get_attribute("lon"));
- return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+ auto y1 = boost::lexical_cast<double>(get_attribute("lat"));
+ auto x1 = boost::lexical_cast<double>(get_attribute("lon"));
+ auto y2 = boost::lexical_cast<double>(previous.get_attribute("lat"));
+ auto x2 = boost::lexical_cast<double>(previous.get_attribute("lon"));
+ return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
#if 0
typedef boost::geometry::model::d2::point_xy<double> point_type;
@@ -67,4 +74,6 @@ Node::getLength(const Node &previous) const {
#endif
}
+
+
} // namespace osm2pgr
diff --git a/src/osm_elements/OSMDocument.cpp b/src/osm_elements/OSMDocument.cpp
new file mode 100644
index 0000000..0735a21
--- /dev/null
+++ b/src/osm_elements/OSMDocument.cpp
@@ -0,0 +1,267 @@
+/***************************************************************************
+ * Copyright (C) 2016 by pgRouting developers *
+ * project at pgrouting.org *
+ * *
+ * 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 t &or 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include "osm_elements/OSMDocument.h"
+
+#include <boost/lexical_cast.hpp>
+#include <vector>
+#include <map>
+#include <utility>
+#include <string>
+#include <iostream>
+#include <algorithm>
+
+#if 0
+#include <sys/wait.h>
+#endif
+
+#include "utilities/utilities.h"
+#include "configuration/configuration.h"
+#include "osm_elements/Node.h"
+#include "osm_elements/Relation.h"
+#include "osm_elements/Way.h"
+#include "database/Export2DB.h"
+
+namespace osm2pgr {
+
+OSMDocument::OSMDocument(
+ const Configuration &config,
+ const po::variables_map &vm,
+ const Export2DB &db_conn,
+ size_t lines) :
+ m_rConfig(config),
+ m_vm(vm),
+ m_db_conn(db_conn),
+ m_chunk_size(vm["chunk"].as<size_t>()),
+ m_nodeErrs(0),
+ m_lines(lines) {
+}
+
+
+void
+OSMDocument::wait_child() const {
+#if 0
+ while (true) {
+ int status;
+ pid_t done = wait(&status);
+ if (done == -1) {
+ if (errno == ECHILD) break; // no more child processes
+ } else {
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ cerr << "pid " << done << " failed" << endl;
+ exit(1);
+ }
+ }
+ }
+#endif
+}
+
+
+void
+OSMDocument::AddNode(const Node &n) {
+ if (m_vm.count("addnodes")) {
+ if ((m_nodes.size() % m_chunk_size) == 0) {
+ wait_child();
+ std::cout << "\rCurrent osm_nodes:\t" << m_nodes.size();
+ osm_table_export(m_nodes, "osm_nodes");
+ export_pois();
+ }
+ }
+
+ m_nodes.push_back(n);
+}
+
+void OSMDocument::AddWay(const Way &w) {
+ if (m_ways.empty() && m_vm.count("addnodes")) {
+ wait_child();
+ osm_table_export(m_nodes, "osm_nodes");
+ std::cout << "\nFinal osm_nodes:\t" << m_nodes.size();
+ export_pois();
+ }
+
+
+ if (m_vm.count("addnodes")) {
+ if ((m_ways.size() % m_chunk_size) == 0) {
+ wait_child();
+ if (m_ways.size() % 200000 == 0) {
+ std::cout << "\nCurrent osm_ways:\t" << m_ways.size();
+ }
+ osm_table_export(m_ways, "osm_ways");
+ }
+ }
+
+ m_ways.push_back(w);
+}
+
+void
+OSMDocument::AddRelation(const Relation &r) {
+ if (m_vm.count("addnodes") && m_relations.empty()) {
+ wait_child();
+ osm_table_export(m_ways, "osm_ways");
+ std::cout << "\nFinal osm_ways:\t" << m_ways.size();
+ }
+
+ if (m_vm.count("addnodes")) {
+ wait_child();
+ if (m_relations.size() % 100000 == 0) {
+ std::cout << "\nCurrent osm_relations:\t" << m_relations.size();
+ }
+ osm_table_export(m_relations, "osm_relations");
+ }
+ m_relations.push_back(r);
+}
+
+void
+OSMDocument::endOfFile() const {
+ if (m_vm.count("addnodes")) {
+ wait_child();
+ osm_table_export(m_relations, "osm_relations");
+ std::cout << "\nEnd Of file\n\n\n";
+ }
+}
+
+
+template <typename T>
+static
+bool
+less(const T &item, const int64_t &id) {
+ return item.osm_id() < id;
+}
+
+
+Node*
+OSMDocument::FindNode(int64_t node_id) {
+ auto it = std::lower_bound(m_nodes.begin(), m_nodes.end(), node_id, less<Node>);
+ return &*it;
+}
+
+bool
+OSMDocument::has_node(int64_t node_id) const {
+ auto it = std::lower_bound(m_nodes.begin(), m_nodes.end(), node_id, less<Node>);
+ return (it != m_nodes.end());
+}
+
+Way*
+OSMDocument::FindWay(int64_t way_id) {
+ auto it = std::lower_bound(m_ways.begin(), m_ways.end(), way_id, less<Way>);
+ return &*it;
+}
+
+bool
+OSMDocument::has_way(int64_t way_id) const {
+ auto it = std::lower_bound(m_ways.begin(), m_ways.end(), way_id, less<Way>);
+ return (it != m_ways.end());
+}
+
+void
+OSMDocument::add_node(Way &way, const char **atts) {
+ auto **attribut = atts;
+ std::string key = *attribut++;
+ std::string value = *attribut++;
+ auto node_id = (key == "ref")? boost::lexical_cast<int64_t>(value): -1;
+ way.add_node(node_id);
+
+#if 1
+ // TODO leave this when splitting
+ if (!has_node(node_id)) {
+ ++m_nodeErrs;
+ } else {
+ auto node = FindNode(node_id);
+ node->incrementUse();
+ way.add_node(node);
+ }
+#endif
+}
+
+/*
+ * for example
+ * <tag highway="kerb">
+ *
+ *
+ * And the configuration file has:
+ * <type name="highway" id="1">
+ * <class name="kerb" id="101" priority="1.0" maxspeed="130" />
+ *
+ */
+
+void
+OSMDocument::add_config(Element *item, const Tag &tag) const {
+ auto k = tag.key();
+ auto v = tag.value();
+ if (config_has_tag(tag)) {
+ if (!(item->is_tag_configured())
+ || (config_has_tag(item->tag_config())
+ && m_rConfig.priority(tag) < m_rConfig.priority(item->tag_config())
+ )) {
+ item->tag_config(tag);
+ }
+ }
+}
+
+static
+bool
+has_no_tags(const Node &node) {
+ return !node.has_tags();
+}
+
+void
+OSMDocument::export_pois() const {
+ std::string table("pointsofinterest");
+ if (m_nodes.empty()) return;
+
+#if 0
+ if (m_vm.count("fork")) {
+ auto pid = fork();
+ if (pid < 0) {
+ std::cerr << "Failed to fork" << endl;
+ exit(1);
+ }
+ if (pid > 0) return;
+ }
+#endif
+
+
+ auto residue = m_nodes.size() % m_chunk_size;
+ size_t start = residue? m_nodes.size() - residue : m_nodes.size() - m_chunk_size;
+
+ auto export_items = Nodes(m_nodes.begin() + start, m_nodes.end());
+ /*
+ * deleting nodes with no tag information
+ */
+ export_items.erase(
+ std::remove_if(export_items.begin(), export_items.end(), has_no_tags),
+ export_items.end());
+
+ if (!export_items.empty()) {
+ m_db_conn.export_osm(export_items, table);
+ }
+
+#if 0
+ if (m_vm.count("fork")) {
+ /*
+ * finish the child process
+ */
+ _exit(0);
+ }
+#endif
+}
+
+
+} // namespace osm2pgr
diff --git a/src/Relation.cpp b/src/osm_elements/Relation.cpp
similarity index 85%
rename from src/Relation.cpp
rename to src/osm_elements/Relation.cpp
index 0d2fcd3..d7f2228 100644
--- a/src/Relation.cpp
+++ b/src/osm_elements/Relation.cpp
@@ -21,7 +21,7 @@
#include <boost/lexical_cast.hpp>
#include <string>
-#include "./Relation.h"
+#include "osm_elements/Relation.h"
namespace osm2pgr {
@@ -57,6 +57,21 @@ Relation::add_member(const char **atts) {
return osm_id;
}
+std::string
+Relation::members_str() const {
+ std::string way_list("");
+ for (const auto &way_ref : m_WayRefs) {
+ way_list += boost::lexical_cast<std::string>(way_ref)
+ /*
+ * currently only adding way
+ */
+ + "=>\"type=>way,role=>TODO\"" + ",";
+ }
+ way_list[way_list.size() -1] = ' ';
+
+ return way_list;
+}
+
} // end namespace osm2pgr
diff --git a/src/Way.cpp b/src/osm_elements/Way.cpp
similarity index 87%
rename from src/Way.cpp
rename to src/osm_elements/Way.cpp
index a4ffa4e..6fa2cf3 100644
--- a/src/Way.cpp
+++ b/src/osm_elements/Way.cpp
@@ -19,7 +19,7 @@
***************************************************************************/
-#include "Way.h"
+#include "osm_elements/Way.h"
#include "boost/lexical_cast.hpp"
#include <algorithm>
#include <string>
@@ -27,9 +27,9 @@
#include <map>
#include <vector>
#include <iostream>
-#include "./OSMDocument.h"
-#include "./osm_tag.h"
-#include "./Node.h"
+#include "osm_elements/OSMDocument.h"
+#include "osm_elements/osm_tag.h"
+#include "osm_elements/Node.h"
@@ -40,13 +40,13 @@ Way::Way(const char **atts) :
Element(atts),
m_maxspeed_forward(-1),
m_maxspeed_backward(-1),
- m_oneWay("UNKNOWN") { }
-
-
+ m_oneWay("UNKNOWN") {
+ }
Tag
Way::add_tag(const Tag &tag) {
m_tags[tag.key()] = tag.value();
+ implied_oneWay(tag);
oneWay(tag);
max_speed(tag);
return tag;
@@ -54,15 +54,19 @@ Way::add_tag(const Tag &tag) {
void
+Way::add_node(int64_t node_id) {
+ m_node_ids.push_back(node_id);
+}
+
+void
Way::add_node(Node *node) {
assert(node);
m_NodeRefs.push_back(node);
}
-
std::string
-Way::geometry_str() const {
+Way::get_geometry() const {
return geometry_str(m_NodeRefs);
}
@@ -74,7 +78,9 @@ Way::length_str() const {
std::string
Way::geometry_str(const std::vector<Node*> &nodeRefs) const {
- std::string geometry("LINESTRING(");
+ if (nodeRefs.size() < 2) return "srid=4326;LINESTRING EMPTY";
+
+ std::string geometry("srid=4326;LINESTRING(");
for (auto it = nodeRefs.begin();
it != nodeRefs.end();
@@ -150,18 +156,20 @@ Way::split_me() {
std::string
Way::oneWay() const {
- return m_oneWay;
+ return static_cast<std::string>(m_oneWay);
}
void
Way::oneWay(const Tag &tag) {
auto key = tag.key();
auto value = tag.value();
+
if (key != "oneway") {
- implied_oneWay(tag);
return;
}
+ if (m_oneWay != "UNKNOWN") return;
+
// one way tag
if ((value == "yes") || value == "true" || value == "1") {
m_oneWay = "YES";
@@ -196,7 +204,7 @@ Way::implied_oneWay(const Tag &tag) {
|| (key == "highway"
&& (value == "motorway"
|| value == "trunk") )) {
- m_oneWay == "YES";
+ m_oneWay = "YES";
return;
}
@@ -204,7 +212,7 @@ Way::implied_oneWay(const Tag &tag) {
&& (value == "primary"
|| value == "secondary"
|| value == "tertiary")) {
- m_oneWay == "NO";
+ m_oneWay = "NO";
return;
}
}
@@ -224,7 +232,7 @@ Way::pedestrian(const std::string &key, const std::string &value) {
|| (key == "highway" && value == "cycleway")
|| (key == "highway" && value == "bridleway")
|| (key == "highway" && value == "track")
- || (key == "sidewak" && value != "no") )
+ || (key == "sidewalk" && value != "no") )
|| (key == "foot" && value != "no") )
|| (key == "highway" && value == "steps") {
m_pedestrian = "YES";
@@ -256,7 +264,7 @@ Way::get_kph(const std::string &value) const {
}
}
- mph_pos = value.find(" knots");
+ mph_pos = value.find("knots");
if (mph_pos != std::string::npos) {
auto newstr = value;
newstr.erase(mph_pos, std::string::npos);
@@ -284,21 +292,17 @@ void
Way::max_speed(const Tag &tag) {
auto key = tag.key();
auto value = tag.value();
- if (key == "maxspeed:forward" && m_maxspeed_forward <=0) {
+ if (key == "maxspeed:forward") {
m_maxspeed_forward = get_kph(value);
return;
}
- if (key == "maxspeed:backward" && m_maxspeed_backward <=0) {
+ if (key == "maxspeed:backward") {
m_maxspeed_backward = get_kph(value);
return;
}
if (key == "maxspeed") {
- if (m_maxspeed_forward <=0) {
- m_maxspeed_forward = get_kph(value);
- }
- if (m_maxspeed_backward <=0) {
- m_maxspeed_backward = get_kph(value);
- }
+ m_maxspeed_backward = get_kph(value);
+ m_maxspeed_forward = get_kph(value);
return;
}
}
@@ -322,6 +326,18 @@ Way::insert_tags(const std::map<std::string, std::string> &tags) {
}
}
+std::string
+Way::members_str() const {
+ /* this list comes from the node_ids becuase a node might not be on the file */
+ 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;
+}
+
#ifndef NDEBUG
diff --git a/src/osm2pgrouting.cpp b/src/osm_elements/osm2pgrouting.cpp
similarity index 60%
rename from src/osm2pgrouting.cpp
rename to src/osm_elements/osm2pgrouting.cpp
index ecbbd22..ca7250a 100644
--- a/src/osm2pgrouting.cpp
+++ b/src/osm_elements/osm2pgrouting.cpp
@@ -32,11 +32,41 @@
#include <chrono>
#endif
-#include "./ConfigurationParserCallback.h"
-#include "./OSMDocumentParserCallback.h"
-#include "./OSMDocument.h"
-#include "./Export2DB.h"
-#include "./prog_options.h"
+#include <pqxx/pqxx>
+
+#include "parser/ConfigurationParserCallback.h"
+#include "parser/OSMDocumentParserCallback.h"
+#include "osm_elements/OSMDocument.h"
+#include "database/Export2DB.h"
+#include "utilities/handle_pgpass.h"
+#include "utilities/prog_options.h"
+
+static
+size_t lines_in_file(const std::string file_name) {
+ FILE *in;
+ char buff[512];
+ std::string command = "wc -l " + file_name;
+
+ if (!(in = popen(command.c_str(), "r"))) {
+ std::cerr << "File not found" << file_name << "\n";
+ exit(1);
+ }
+
+ std::string word;
+ if (fgets(buff, 512, in) != NULL) {
+ word = buff;
+ }
+ pclose(in);
+ std::istringstream iss(word);
+ std::string number;
+ iss >> number;
+ try {
+ return boost::lexical_cast<size_t>(number);
+ } catch (...) {
+ std::cerr << "File not found" << file_name << "\n";
+ exit(1);
+ }
+}
int main(int argc, char* argv[]) {
@@ -51,6 +81,7 @@ int main(int argc, char* argv[]) {
std::chrono::steady_clock::time_point begin_elapsed =
std::chrono::steady_clock::now();
#endif
+
try {
po::options_description od_desc("Allowed options");
get_option_description(od_desc);
@@ -65,7 +96,7 @@ int main(int argc, char* argv[]) {
}
if (vm.count("version")) {
- std::cout << "This is osm2pgrouting Version 2.2\n";
+ std::cout << "This is osm2pgrouting Version 2.3\n";
return 0;
}
@@ -86,19 +117,70 @@ int main(int argc, char* argv[]) {
auto dataFile(vm["file"].as<string>());
auto confFile(vm["conf"].as<string>());
- auto skipnodes(!vm.count("addnodes"));
auto clean(vm.count("clean"));
+ auto no_index(vm.count("no-index"));
+
+ handle_pgpass(vm);
+ std::string connection_str(
+ "host=" + vm["host"].as<std::string>()
+ + " user=" + vm["username"].as<std::string>()
+ + " dbname=" + vm["dbname"].as<std::string>()
+ + " port=" + vm["port"].as<std::string>()
+ + " password=" + vm["password"].as<std::string>());
+ try {
+ cout << "Testing database connection: "
+ << vm["dbname"].as<std::string>()
+ << endl;
+ pqxx::connection C(connection_str);
+ if (C.is_open()) {
+ cout << "database connection successfull: " << C.dbname() << endl;
+ } else {
+ cout << "Can't open database" << endl;
+ return 1;
+ }
+ C.disconnect ();
+ }catch (const std::exception &e){
+ cerr << e.what() << std::endl;
+ return 1;
+ }
-
+ /*
+ * preparing the databasse
+ */
std::cout << "Connecting to the database" << endl;
- osm2pgr::Export2DB dbConnection(vm);
+ osm2pgr::Export2DB dbConnection(vm, connection_str);
if (dbConnection.connect() == 1)
return 1;
- if (!dbConnection.has_postGIS()) {
+
+#ifndef NDEBUG
+ dbConnection.install_postGIS();
+#endif
+
+ if (!dbConnection.has_extension("postgis")) {
std::cout << "ERROR: postGIS not found\n";
+ std::cout << " HINT: CREATE EXTENSION postGIS\n";
return 1;
}
+ if ((vm.count("attributes") || vm.count("tags"))
+ && !dbConnection.has_extension("hstore")) {
+ std::cout << "ERROR: hstore not found\n";
+ std::cout << " HINT: CREATE EXTENSION hstore\n";
+ return 1;
+ }
+ 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
+ */
std::cout << "Opening configuration file: " << confFile.c_str() << endl;
osm2pgr::Configuration config;
@@ -109,57 +191,56 @@ int main(int argc, char* argv[]) {
xml::XMLParser parser;
int ret = parser.Parse(cCallback, confFile.c_str());
if (ret != 0) {
- cout << "Failed to open / parse config file "
+ cout << "Failed to open / parse config file\n"
<< confFile.c_str()
<< endl;
return 1;
}
+ std::cout << "Exporting configuration ...\n";
+ dbConnection.export_configuration(config.types());
+ std::cout << " - Done \n";
- size_t total_lines = 100000;
- osm2pgr::OSMDocument document(config, total_lines);
+ std::cout << "Counting lines ...\n";
+ auto total_lines = lines_in_file(dataFile);
+ std::cout << " - Done \n";
+
+ std::cout << "Opening data file: "
+ << dataFile
+ << "\ttotal lines: "
+ << total_lines
+ << endl;
+ osm2pgr::OSMDocument document(config, vm, dbConnection, total_lines);
osm2pgr::OSMDocumentParserCallback callback(document);
- std::cout << " Parsing data (progress line per " << total_lines << " elements)\n" << endl;
+ std::cout << " Parsing data\n" << endl;
ret = parser.Parse(callback, dataFile.c_str());
if (ret != 0) {
cerr << "Failed to open / parse data file " << dataFile << endl;
return 1;
}
std::cout << " Finish Parsing data\n" << endl;
- if (document.nodesErrs()) {
- std::cerr << "******\nNOTICE: Found " << document.nodesErrs() << " node references with no <node ... >\n*****";
+ if (document.nodeErrs()) {
+ std::cerr << "******\nNOTICE: Found " << document.nodeErrs() << " node references with no <node ... >\n*****";
}
//############# Export2DB
{
- if (clean) {
- std::cout << "\nDropping tables..." << endl;
- dbConnection.dropTables();
- }
-
- std::cout << "\nCreating tables..." << endl;
- dbConnection.createTables();
std::cout << "Adding auxiliary tables to database..." << endl;
- if (!skipnodes) {
- std::cout << "\nExport Nodes ..." << endl;
- dbConnection.exportNodes(document.nodes());
- }
- std::cout << "\nExport Types ..." << endl;
- dbConnection.exportTypes(config.types());
- std::cout << "\nExport Classes ..." << endl;
- dbConnection.exportClasses(config.types());
- std::cout << "\nExport Relations ..." << endl;
- dbConnection.exportRelations(document.relations(), config);
- std::cout << "\nExport RelationsWays ..." << endl;
- dbConnection.exportRelationsWays(document.relations(), config);
+
+
std::cout << "\nExport Ways ..." << endl;
dbConnection.exportWays(document.ways(), config);
+ if (!no_index) {
+ std::cout << "\nCreating indexes ..." << endl;
+ dbConnection.createFKeys();
+ }
+
+ std::cout << "\nProcessing Points of Interest ..." << endl;
+ dbConnection.process_pois();
- std::cout << "Creating Foreign Keys ..." << endl;
- dbConnection.createFKeys();
}
@@ -190,7 +271,8 @@ int main(int argc, char* argv[]) {
#endif
std::cout << "#########################" << endl;
- return 0;
+
+ exit(0);
}
catch (exception &e) {
std::cout << e.what() << endl;
diff --git a/src/osm_elements/osm_element.cpp b/src/osm_elements/osm_element.cpp
new file mode 100644
index 0000000..49fd339
--- /dev/null
+++ b/src/osm_elements/osm_element.cpp
@@ -0,0 +1,233 @@
+/***************************************************************************
+ * Copyright (C) 2016 by pgRouting developers *
+ * project at pgrouting.org *
+ * *
+ * 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 t &or 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+
+#include <boost/lexical_cast.hpp>
+#include <map>
+#include <string>
+#include "osm_elements/osm_tag.h"
+#include "osm_elements/osm_element.h"
+
+namespace osm2pgr {
+
+
+Element::Element(const char **atts) :
+ m_visible(true) {
+ auto **attribut = atts;
+ while (*attribut != NULL) {
+ std::string name = *attribut++;
+ std::string value = *attribut++;
+ if (name == "id") {
+ m_osm_id = boost::lexical_cast<int64_t>(value);
+ }
+ if (name == "visible") {
+ m_visible = boost::lexical_cast<bool>(value);
+ }
+ m_attributes[name] = value;
+ }
+ }
+
+void
+Element::tag_config(const Tag &tag) {
+ m_tag_config = tag;
+}
+
+
+Tag
+Element::add_tag(const Tag &tag) {
+ m_tags[tag.key()] = tag.value();
+ return tag;
+}
+
+bool
+Element::has_tag(const std::string& key) const {
+ return m_tags.find(key) != m_tags.end();
+}
+
+std::string
+Element::get_tag(const std::string& key) const {
+ return m_tags.find(key)->second;
+}
+
+
+bool
+Element::is_tag_configured() const {
+ return (m_tag_config.key() != "" && m_tag_config.value() != "");
+}
+
+
+bool
+Element::has_attribute(const std::string& key) const {
+ return m_attributes.find(key) != m_attributes.end();
+}
+
+std::string
+Element::get_attribute(const std::string& key) const {
+ return m_attributes.find(key)->second;
+}
+
+std::string
+Element::attributes_str() const {
+ if (m_tags.empty()) return "\"\"";
+ std::string str("\"");
+ for (auto it = m_attributes.begin(); it != m_attributes.end(); ++it) {
+ auto attribute = *it;
+ str += attribute.first + "=>" + attribute.second + ",";
+ }
+ str[str.size()-1] = '\"';
+ return str;
+}
+
+std::string
+Element::tags_str() const {
+ if (m_tags.empty()) return "";
+ std::string str("\"");
+ for (auto it = m_tags.begin(); it != m_tags.end(); ++it) {
+ auto tag = *it;
+ str += tag.first + "=>" + tag.second + ",";
+ }
+ str[str.size()-1] = '\"';
+ return str;
+}
+
+static
+std::string
+addquotes(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 + "\"";
+}
+
+
+static
+std::string
+getHstore(const std::map<std::string, std::string> &values) {
+ std::string hstore;
+ if (values.empty()) return std::string();
+
+ for (const auto item : values) {
+ hstore += item.first
+ + " => "
+ + addquotes(item.second, true) + ",";
+ }
+ hstore[hstore.size() - 1] = ' ';
+ hstore += "";
+ return hstore;
+}
+
+#if 0
+static
+std::string
+getJSON(const std::map<std::string, std::string> &values) {
+ if (values.empty()) return std::string("{}");
+ std::string json("{");
+ for (const auto item : values) {
+ json += addquotes(item.first, true)
+ + ":"
+ + addquotes(item.second, true) + ",";
+ }
+ json[json.size() - 1] = '}';
+ json += "";
+ return json;
+}
+#endif
+
+std::vector<std::string>
+Element::values(const std::vector<std::string> &columns, bool is_hstore) const {
+ std::vector<std::string> values;
+ for (const auto column : columns) {
+ if (column == "osm_id" || column == "tag_id") {
+ values.push_back(boost::lexical_cast<std::string>(osm_id()));
+ continue;
+ }
+ if (column == "tag_name") {
+ values.push_back(m_tag_config.key());
+ continue;
+ }
+ if (column == "tag_value") {
+ values.push_back(m_tag_config.value());
+ continue;
+ }
+ if (column == "the_geom") {
+ values.push_back(get_geometry());
+ continue;
+ }
+
+ if (column == "members") {
+ values.push_back(members_str());
+ continue;
+ }
+
+ if (column == "attributes") {
+ values.push_back(getHstore(m_attributes));
+ continue;
+ }
+ if (column == "tags") {
+ values.push_back(getHstore(m_tags));
+ if (is_hstore) {};
+
+ continue;
+ }
+ if (has_attribute(column)) {
+ values.push_back(get_attribute(column));
+ continue;
+ }
+ if (has_tag(column)) {
+ values.push_back(get_tag(column));
+ continue;
+ }
+ values.push_back(std::string(""));
+ }
+ return values;
+}
+
+} // namespace osm2pgr
diff --git a/src/osm_tag.cpp b/src/osm_elements/osm_tag.cpp
similarity index 98%
rename from src/osm_tag.cpp
rename to src/osm_elements/osm_tag.cpp
index 6d7cf55..503ed64 100644
--- a/src/osm_tag.cpp
+++ b/src/osm_elements/osm_tag.cpp
@@ -19,7 +19,7 @@
***************************************************************************/
-#include "./osm_tag.h"
+#include "osm_elements/osm_tag.h"
#include <string>
namespace osm2pgr {
diff --git a/src/ConfigurationParserCallback.cpp b/src/parser/ConfigurationParserCallback.cpp
similarity index 79%
rename from src/ConfigurationParserCallback.cpp
rename to src/parser/ConfigurationParserCallback.cpp
index 18b47cd..c0d9173 100644
--- a/src/ConfigurationParserCallback.cpp
+++ b/src/parser/ConfigurationParserCallback.cpp
@@ -18,15 +18,13 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
-#include "./ConfigurationParserCallback.h"
+#include "parser/ConfigurationParserCallback.h"
#include <boost/lexical_cast.hpp>
-
#include <string>
-#include "./OSMDocument.h"
-#include "./Configuration.h"
-#include "./Type.h"
-#include "./Class.h"
+
+#include "osm_elements/OSMDocument.h"
+#include "configuration/configuration.h"
namespace osm2pgr {
@@ -36,18 +34,21 @@ namespace osm2pgr {
void ConfigurationParserCallback::StartElement(
const char *name,
const char** atts) {
- if (strcmp(name, "class") == 0) {
- m_current->add_class(atts);
- } else if (strcmp(name, "type") == 0) {
- m_current = new Type(atts);
+ /* the type is the tag_key */
+ if (strcmp(name, "tag_name") == 0) {
+ m_current = new Tag_key(atts);
+ /* the class is the tag_value */
+ } else if (strcmp(name, "tag_value") == 0) {
+ m_current->add_tag_value(Tag_value(atts));
} else if (strcmp(name, "configuration") == 0) {
}
}
void ConfigurationParserCallback::EndElement(const char* name) {
- if (strcmp(name, "type") == 0) {
- m_config.AddType(*m_current);
+ /* the type is the tag_key */
+ if (strcmp(name, "tag_name") == 0) {
+ m_config.add_tag_key(*m_current);
delete m_current;
}
}
diff --git a/src/OSMDocumentParserCallback.cpp b/src/parser/OSMDocumentParserCallback.cpp
similarity index 77%
rename from src/OSMDocumentParserCallback.cpp
rename to src/parser/OSMDocumentParserCallback.cpp
index 1c3621c..68df9fb 100644
--- a/src/OSMDocumentParserCallback.cpp
+++ b/src/parser/OSMDocumentParserCallback.cpp
@@ -20,19 +20,19 @@
-#include "./OSMDocumentParserCallback.h"
+#include "parser/OSMDocumentParserCallback.h"
#include <math.h>
#include <string>
#include <cassert>
#include <iostream>
#include <sstream>
-#include "./OSMDocument.h"
-#include "./print_progress.h"
-#include "./Relation.h"
-#include "./osm_tag.h"
-#include "./Way.h"
-#include "./Node.h"
+#include "osm_elements/OSMDocument.h"
+#include "osm_elements/Relation.h"
+#include "osm_elements/osm_tag.h"
+#include "osm_elements/Way.h"
+#include "osm_elements/Node.h"
+#include "utilities/print_progress.h"
namespace osm2pgr {
@@ -56,9 +56,15 @@ namespace osm2pgr {
void
OSMDocumentParserCallback::show_progress() {
- if ((++m_line % (m_rDocument.lines() / 100)) == 0) {
- print_progress(m_rDocument.lines(), m_line % m_rDocument.lines());
- std::cout << " Total osm elements parsed: " << m_line;
+ try {
+ if (m_line == 0) return;
+ assert(m_rDocument.lines());
+ if (m_rDocument.lines() == 0) return;
+ if (((++m_line) % (m_rDocument.lines() / 100)) == 0) {
+ print_progress(m_rDocument.lines(), m_line);
+ }
+ } catch(...) {
+ m_line = 1;
}
}
@@ -81,12 +87,10 @@ OSMDocumentParserCallback::StartElement(
if (strcmp(name, "node") == 0) {
last_node = new Node(atts);
}
-#if 0
- // TODO(vicky) to be used in V.3 for a hstore column
if (strcmp(name, "tag") == 0) {
- last_node->add_tag(Tag(atts));
+ auto tag = last_node->add_tag(Tag(atts));
+ m_rDocument.add_config(last_node, tag);
}
-#endif
return;
}
@@ -96,7 +100,7 @@ OSMDocumentParserCallback::StartElement(
}
if (strcmp(name, "tag") == 0) {
auto tag = last_way->add_tag(Tag(atts));
- m_rDocument.add_config(*last_way, tag);
+ m_rDocument.add_config(last_way, tag);
}
if (strcmp(name, "nd") == 0) {
@@ -134,55 +138,46 @@ OSMDocumentParserCallback::StartElement(
return;
}
if (strcmp(name, "tag") == 0) {
- if (atts != NULL) {
- auto tag = last_relation->add_tag(Tag(atts));
- if (!tag.key().empty()) {
- if ((last_relation->tag_config().key() == "" && last_relation->tag_config().value() == "")
- || (m_rDocument.has_class(tag)
- && m_rDocument.has_class(last_relation->tag_config())
- && (m_rDocument.class_priority(tag)
- < m_rDocument.class_priority(last_relation->tag_config())))) {
- last_relation->tag_config(tag);
- }
- }
- }
+ auto tag = last_relation->add_tag(Tag(atts));
+ m_rDocument.add_config(last_relation, tag);
}
} else if (strcmp(name, "osm") == 0) {
}
}
void OSMDocumentParserCallback::EndElement(const char* name) {
+ if (strcmp(name, "osm") == 0) {
+ return;
+ }
if (strcmp(name, "node") == 0) {
m_rDocument.AddNode(*last_node);
delete last_node;
return;
}
if (strcmp(name, "way") == 0) {
- if (m_rDocument.has_class(last_way->tag_config())) {
- auto newValue = m_rDocument.class_default_maxspeed(
- last_way->tag_config());
+ m_rDocument.AddWay(*last_way);
+ if (m_rDocument.config_has_tag(last_way->tag_config())) {
+ auto maxspeed = m_rDocument.maxspeed(last_way->tag_config());
if (last_way->maxspeed_forward() <= 0) {
- last_way->maxspeed_forward(newValue);
+ last_way->maxspeed_forward(maxspeed);
}
if (last_way->maxspeed_backward() <= 0) {
- last_way->maxspeed_backward(newValue);
+ last_way->maxspeed_backward(maxspeed);
}
}
-
- m_rDocument.AddWay(*last_way);
delete last_way;
return;
} else if (strcmp(name, "relation") == 0) {
- if (m_rDocument.has_class(last_relation->tag_config())) {
+ 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) {
auto way_id = *it;
assert(m_rDocument.has_way(way_id));
if (m_rDocument.has_way(way_id)) {
Way* way_ptr = m_rDocument.FindWay(way_id);
way_ptr->tag_config(last_relation->tag_config());
- auto newValue = m_rDocument.class_default_maxspeed(
+ auto newValue = m_rDocument.maxspeed(
last_relation->tag_config());
if (way_ptr->maxspeed_forward() <= 0) {
way_ptr->maxspeed_forward(newValue);
@@ -192,11 +187,12 @@ void OSMDocumentParserCallback::EndElement(const char* name) {
}
}
}
- m_rDocument.AddRelation(*last_relation);
}
+ m_rDocument.AddRelation(*last_relation);
delete last_relation;
} else if (strcmp(name, "osm") == 0) {
+ m_rDocument.endOfFile();
show_progress();
}
}
diff --git a/src/XMLParser.cpp b/src/parser/XMLParser.cpp
similarity index 98%
rename from src/XMLParser.cpp
rename to src/parser/XMLParser.cpp
index 1a20f74..5ece1d3 100644
--- a/src/XMLParser.cpp
+++ b/src/parser/XMLParser.cpp
@@ -19,7 +19,7 @@
***************************************************************************/
-#include "./XMLParser.h"
+#include "parser/XMLParser.h"
#include <errno.h>
#include <string.h>
@@ -74,6 +74,7 @@ int XMLParser::Parse(XMLParserCallback& rCallback, const char* chFileName) {
fclose(fp);
ret = 2; // quit, return = 2 indicating parsing error
done = 1;
+ return ret;
}
} while (!done);
diff --git a/src/utilities/handle_pgpass.cpp b/src/utilities/handle_pgpass.cpp
new file mode 100644
index 0000000..009ba7f
--- /dev/null
+++ b/src/utilities/handle_pgpass.cpp
@@ -0,0 +1,94 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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*/
+
+
+#include <iostream>
+#include <boost/program_options.hpp>
+#include <sys/stat.h>
+#include <fstream>
+#include <cstdlib>
+#include <string>
+#include <unistd.h>
+
+namespace po = boost::program_options;
+
+void
+handle_pgpass(po::variables_map &vm) {
+
+ if (!vm["password"].as<std::string>().empty()) {
+ /*
+ * nothing to do password is given
+ */
+ return;
+ }
+
+
+
+ std::string file;
+ auto filename(getenv("PGPASSFILE"));
+ if (!filename) {
+#if 0
+ std::cout << "No PGPASSFILE found \n";
+ std::cout << "Looking for .pgpass \n";
+#endif
+ auto homedir(getenv("HOME"));
+ if (!homedir) {
+ std::cout << "No $HOME found \n";
+ return;
+ }
+#if 0
+ std::cout << "home directory" << homedir << "\n";
+#endif
+ file = std::string(homedir) + "/.pgpass";
+ }
+ else {
+ file = filename;
+ }
+ std::ifstream infile(file.c_str());
+ if (!infile.good()) {
+ return;
+ }
+
+
+ std::string host;
+ std::string port;
+ std::string dbase;
+ std::string user;
+ std::string passwd;
+ std::string username = vm["username"].as<std::string>().empty() ?
+ getenv("USER") : vm["username"].as<std::string>();
+ vm.at("username").value() = username;
+ while (std::getline(infile, host, ':')) {
+ std::getline(infile, port, ':');
+ std::getline(infile, dbase, ':');
+ std::getline(infile, user, ':');
+ std::getline(infile, passwd);
+ if ((host == "" || host == "*" || host == vm["host"].as<std::string>())
+ && (port == "*" || port == vm["port"].as<std::string>())
+ && (dbase == "*" || dbase == vm["dbname"].as<std::string>())
+ && (user == "*" || user == username)
+ && (dbase == "*" || host == vm["dbname"].as<std::string>())) {
+ infile.close();
+ std::cout << passwd << "\n";
+ vm.at("password").value() = passwd;
+ return;
+ }
+ }
+ return;
+}
diff --git a/src/prog_options.cpp b/src/utilities/prog_options.cpp
similarity index 79%
rename from src/prog_options.cpp
rename to src/utilities/prog_options.cpp
index 55c89ad..79446f7 100644
--- a/src/prog_options.cpp
+++ b/src/utilities/prog_options.cpp
@@ -51,13 +51,24 @@ void get_option_description(po::options_description &od_desc) {
("schema", po::value<std::string>()->default_value(""), "Database schema to put tables.\n blank:\t defaults to default schema dictated by PostgreSQL search_path.")
("prefix", po::value<std::string>()->default_value(""), "Prefix added at the beginning of the table names.")
("suffix", po::value<std::string>()->default_value(""), "Suffix added at the end of the table names.")
- ("addnodes", "Import the osm_nodes table.")
- ("clean", "Drop previously created tables.");
+ ("postgis", "Install postgis if not found.") // TODO(vicky) remove before realesing
+ ("addnodes", "Import the osm_nodes, osm_ways & osm_relations tables.")
+ ("attributes", "Include attributes information.")
+ ("tags", "Include tag information.")
+ ("chunk", po::value<std::size_t>()->default_value(20000), "Exporting chunk size.")
+ ("clean", "Drop previously created tables.")
+ ("no-index", "Do not create indexes (Use when indexes are already created)");
+#if 0
+ ("addways", "Import the osm_ways table.")
+ ("addrelations", "Import the osm_relations table.")
+ ("fork", "Use fork (works on small files).");
+ ("hstore", "Use hstore for attributes and/or tags. (not indicating will use json)")
+#endif
db_options_od_desc.add_options()
// database options
("dbname,d", po::value<std::string>()->required(), "Name of your database (Required).")
- ("username,U", po::value<std::string>()->default_value("postgres"), "Name of the user, which have write access to the database.")
+ ("username,U", po::value<std::string>()->default_value(""), "Name of the user, which have write access to the database.")
("host,h", po::value<std::string>()->default_value("localhost"), "Host of your postgresql database.")
("port,p", po::value<std::string>()->default_value("5432"), "db_port of your database.")
("password,W", po::value<std::string>()->default_value(""), "Password for database access.");
@@ -89,7 +100,14 @@ process_command_line(po::variables_map &vm) {
std::cout << "schema= " << vm["schema"].as<std::string>() << "\n";
std::cout << "prefix = " << vm["prefix"].as<std::string>() << "\n";
std::cout << "suffix = " << vm["suffix"].as<std::string>() << "\n";
+ std::cout << (vm.count("postgis")? "I" : "Don't I") << "nstall postgis if not found\n";
std::cout << (vm.count("clean")? "D" : "Don't d") << "rop tables\n";
- std::cout << (vm.count("addnodes")? "A" : "Don't a") << "dd nodes\n";
+ std::cout << (vm.count("no-index")? "D" : "Don't c") << "reate indexes\n";
+ std::cout << (vm.count("addnodes")? "A" : "Don't a") << "dd OSM nodes\n";
+ std::cout << (vm.count("addways")? "A" : "Don't a") << "dd OSM ways\n";
+ std::cout << (vm.count("addrelations")? "A" : "Don't a") << "dd OSM relations\n";
+#if 0
+ std::cout << (vm.count("fork")? "F" : "Don't f") << "ork\n";
+#endif
std::cout << "***************************************************\n";
}
diff --git a/src/utilities/utilities.cpp b/src/utilities/utilities.cpp
new file mode 100644
index 0000000..0514bd4
--- /dev/null
+++ b/src/utilities/utilities.cpp
@@ -0,0 +1,47 @@
+/*PGR-GNU*****************************************************************
+
+ Copyright (c) 2017 pgRouting developers
+ Mail: project at pgrouting.org
+
+ ------
+ 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*/
+
+#include <string>
+#include <vector>
+
+
+
+std::string
+comma_separated(const std::vector<std::string> &columns) {
+ std::string result(" ");
+ for (auto column: columns) {
+ result += column + ",";
+ }
+ result[result.size() - 1] = ' ';
+ return result;
+}
+
+std::string
+tab_separated(const std::vector<std::string> &columns) {
+ std::string result(" ");
+ for (auto column: columns) {
+ if (column.empty() || column == "") {
+ result += "\\N\t";
+ } else {
+ result += column + "\t";
+ }
+ }
+ result[result.size() - 1] = '\n';
+ return result;
+}
diff --git a/tools/data/getdata.sh b/tools/data/getdata.sh
index 0dd00e9..c0659de 100644
--- a/tools/data/getdata.sh
+++ b/tools/data/getdata.sh
@@ -12,3 +12,5 @@ wget --progress=dot:mega -O "sampledataSW.osm" "http://www.overpass-api.de/api/x
BBOX="-122.65,45.4, -122.6,45.45"
wget --progress=dot:mega -O "small.osm" "http://www.overpass-api.de/api/xapi?*[bbox=${BBOX}][@meta]"
+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]"
diff --git a/tools/doxygen/Doxyfile b/tools/doxygen/Doxyfile
index ec9050e..5fb7f4b 100644
--- a/tools/doxygen/Doxyfile
+++ b/tools/doxygen/Doxyfile
@@ -44,14 +44,14 @@ PROJECT_NUMBER = 2.1
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.
-PROJECT_BRIEF = "osm2pgrouting provides the tools to import to a SQL geospatial database the routabla data from osm."
+PROJECT_BRIEF = "osm2pgrouting provides the tools to import to a SQL geospatial database the routable data from osm."
# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
# the documentation. The maximum height of the logo should not exceed 55 pixels
# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
# to the output directory.
-PROJECT_LOGO = "../../doc/static/images/pgrouting-logo.png"
+PROJECT_LOGO = "./images/pgrouting-logo.png"
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
@@ -742,7 +742,7 @@ WARN_FORMAT = "$file:$line: $text"
# messages should be written. If left blank the output is written to standard
# error (stderr).
-WARN_LOGFILE =
+WARN_LOGFILE = "LOG.txt"
#---------------------------------------------------------------------------
# Configuration options related to the input files
@@ -805,7 +805,7 @@ EXCLUDE_SYMLINKS = NO
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*
-EXCLUDE_PATTERNS = */notUsed/*
+EXCLUDE_PATTERNS = */notUsed/* */tools/* */build/* */fix_typos/*
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@@ -842,7 +842,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).
-IMAGE_PATH = ../../doc/static/images/developers/
+IMAGE_PATH = ./images
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@@ -2237,7 +2237,7 @@ DOT_PATH =
# command).
# This tag requires that the tag HAVE_DOT is set to YES.
-DOTFILE_DIRS = ../doc/images/
+DOTFILE_DIRS = ./images
# The MSCFILE_DIRS tag can be used to specify one or more directories that
# contain msc files that are included in the documentation (see the \mscfile
diff --git a/tools/doxygen/images/pgrouting-logo.png b/tools/doxygen/images/pgrouting-logo.png
new file mode 100644
index 0000000..f65824f
Binary files /dev/null and b/tools/doxygen/images/pgrouting-logo.png differ
--
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