diff --git a/.github/workflows/libpqxx.yml b/.github/workflows/libpqxx.yml deleted file mode 100644 index d1c5af6a..00000000 --- a/.github/workflows/libpqxx.yml +++ /dev/null @@ -1,95 +0,0 @@ -name: Supported versions of libpqxx - -on: - push: - branches-ignore: - - 'translations_*' - tags: [] - pull_request: - paths-ignore: - - '**.po' - - -jobs: - build: - name: Build - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - matrix: - libpqxx: [6, 7] - os: [ubuntu-latest] - - steps: - - uses: actions/checkout@v2 - - - name: Get postgres version - run: | - sudo service postgresql start - pgver=$(psql --version | grep -Po '(?<=psql \(PostgreSQL\) )[^;]+(?=\.\d \()') - echo "PGVER=${pgver}" >> $GITHUB_ENV - echo "PGIS=3" >> $GITHUB_ENV - - - name: Add PostgreSQL APT repository - run: | - sudo apt-get install curl ca-certificates gnupg - curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - - sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ \ - $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y \ - libboost-program-options-dev \ - libtap-parser-sourcehandler-pgtap-perl \ - postgresql-${PGVER} \ - postgresql-${PGVER}-pgtap \ - postgresql-${PGVER}-postgis-${PGIS} \ - postgresql-${PGVER}-postgis-${PGIS}-scripts \ - postgresql-${PGVER}-pgrouting \ - postgresql-server-dev-${PGVER} - - - - name: Install libpqxx-dev v6 - if: matrix.libpqxx == 6 - run: | - sudo apt-get install -y \ - libpqxx-dev - - - name: download libpqxx-dev v7 - if: matrix.libpqxx == 7 - uses: actions/checkout@master - with: - repository: jtv/libpqxx - path: ./libpqxx - - - name: Install libpqxx-dev v7 - if: matrix.libpqxx == 7 - run: | - cd ./libpqxx - cmake -DSKIP_BUILD_TEST=on . - cmake --build . - sudo cmake --install . - - - - name: Configure - run: | - export PATH=/usr/lib/postgresql/${PGVER}/bin:$PATH - mkdir build - cd build - cmake -DPOSTGRESQL_VERSION=${PGVER} -DCMAKE_BUILD_TYPE=Release -DWITH_DOC=OFF .. - - - name: Build - run: | - cd build - make -j 4 - sudo make install - - - name: Test - if: false - run: | - sudo service postgresql start - sudo -u postgres createdb -p ${PGPORT} ___vrp___test___ - sudo -u postgres bash ./tools/testers/pg_prove_tests.sh postgres ${PGPORT} Release diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index c79bc2cb..949450f7 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -1,45 +1,58 @@ name: Build for Ubuntu +# manually triggered workflow + on: + workflow_dispatch: push: - branches-ignore: - - 'translations_*' - tags: [] pull_request: - paths-ignore: - - '**.po' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + jobs: build: - name: Build + name: Ubuntu psql runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - psql: [9.6,10,11,12, 13] - postgis: [2.5,3] - os: [ubuntu-latest] + psql: [13, 14, 15, 16, 17, 18] + postgis: [3] + release: [Debug, Release] + os: [ubuntu-latest, ubuntu-22.04] + compiler: [ gcc-latest, g++-11, clang ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v5 - - name: get postgres version + - name: 'Raise Priority for apt.postgresql.org' run: | - sudo service postgresql start - pgver=$(psql --version | grep -Po '(?<=psql \(PostgreSQL\) )[^;]+(?=\.\d \()') - echo "PGVER=${pgver}" >> $GITHUB_ENV - PGP=5433 - if [ "${{ matrix.psql }}" == "${pgver}" ]; then PGP=5432; fi - echo "PGPORT=${PGP}" >> $GITHUB_ENV + cat << EOF >> ./pgdg.pref + Package: * + Pin: release o=apt.postgresql.org + Pin-Priority: 600 + EOF + sudo mv ./pgdg.pref /etc/apt/preferences.d/ + sudo apt update - name: Add PostgreSQL APT repository run: | - sudo apt-get install curl ca-certificates gnupg - curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - - sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ \ - $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' + sudo apt-get -y purge postgresql-* + sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg-testing main ${{ matrix.psql }}" > /etc/apt/sources.list.d/pgdg.list' + curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null + + - name: Install compiler + id: install_cc + uses: rlalik/setup-cpp-compiler@master + with: + compiler: ${{ matrix.compiler }} - name: Install dependencies run: | @@ -54,23 +67,20 @@ jobs: postgresql-${{ matrix.psql }}-pgrouting \ libpqxx-dev \ postgresql-server-dev-${{ matrix.psql }} + # should be 7 on latest and 6 on 22.04 + apt-cache policy libpqxx-dev - - name: Configure + - name: Configure compiler run: | + export CC=/usr/bin/${{ steps.install_cc.outputs.cc }} + export CXX=/usr/bin/${{ steps.install_cc.outputs.cxx }} export PATH=/usr/lib/postgresql/${{ matrix.psql }}/bin:$PATH mkdir build cd build - cmake -DPOSTGRESQL_VERSION=${{ matrix.psql }} -DCMAKE_BUILD_TYPE=Release -DWITH_DOC=OFF .. + cmake -DCMAKE_BUILD_TYPE=${{ matrix.release }} .. - name: Build run: | cd build make -j 4 sudo make install - - - name: Test - if: false - run: | - sudo service postgresql start - sudo -u postgres createdb -p ${PGPORT} ___vrp___test___ - sudo -u postgres bash ./tools/testers/pg_prove_tests.sh postgres ${PGPORT} Release diff --git a/CMakeLists.txt b/CMakeLists.txt index 632e2036..ebdb4f99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,6 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) + +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) + if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} ) message(FATAL_ERROR "In-source builds not allowed. @@ -6,7 +8,8 @@ if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} ) You may need to remove CMakeCache.txt." ) endif() -PROJECT(osm2pgrouting) +PROJECT(osm2pgrouting VERSION 3.0.0 + LANGUAGES C CXX) LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") SET(SHARE_DIR "${CMAKE_INSTALL_PREFIX}/share/osm2pgrouting") @@ -46,7 +49,7 @@ else() endif() set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FILE_OFFSET_BITS=64") -set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wconversion -pedantic -Wextra -frounding-math -Wno-deprecated -fmax-errors=10") +set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wconversion -pedantic -Wextra -frounding-math -Wno-deprecated") if(WIN32 AND MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_DEPRECATE") diff --git a/NEWS b/NEWS index ac243d90..4ccb6aa0 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,52 @@ +osm2pgRouting 3.0.0 + +* cmake >= 3.12 +* geometry column name: `geom` + +New "ways" table structure + Column | Type | Modifications | Default +-------------------+---------------------------+--------------------+----------- + id | bigint | previously was gid | generated always as identity + 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 | integer | + 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 | + geom | geometry(LineString,4326) | previously was the_geom + +New "ways_vertices_pgr" table structure + + Column | Type | Default +-----------+----------------------+------------------------------------------- + id | bigint | Default: generated always as identity + in_edges | bigint[] | New column + out_edges | bigint[] | New column + x | numeric(11,8) | Default: generated always as (st_x(geom)) stored + y | numeric(11,8) | Default: generated always as (st_y(geom)) stored + osm_id | bigint | + geom | geometry(Point,4326) + osm2pgRouting 2.3.9 -* +* Homebrew: Add algorithm for std::transform osm2pgRouting 2.3.8 diff --git a/ci/travis/install-libpqxx.sh b/ci/travis/install-libpqxx.sh deleted file mode 100755 index 33ad002e..00000000 --- a/ci/travis/install-libpqxx.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/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/install-postgres.sh b/ci/travis/install-postgres.sh deleted file mode 100755 index ecab98f9..00000000 --- a/ci/travis/install-postgres.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash -# ------------------------------------------------------------------------------ -# Travis CI scripts -# Copyright(c) pgRouting Contributors -# -# Install pgRouting prerequesits -# ------------------------------------------------------------------------------ - -set -e - -POSTGRESQL_VERSION="$1" -PGUSER="$2" - -if [[ -z "$POSTGRESQL_VERSION" ]] ; then - exit 1 -fi - - -if [[ "$POSTGRESQL_VERSION" = "9.5" || "$POSTGRESQL_VERSION" = "9.6" ]] ; then - POSTGIS_VERSION="2.3" -fi - -echo "Postgres $POSTGRESQL_VERSION" -echo "User $PGUSER" - -sudo /etc/init.d/postgresql stop -sudo apt-get install -y \ - postgresql-server-dev-$POSTGRESQL_VERSION - -if [[ "$POSTGRESQL_VERSION" = "9.5" || "$POSTGRESQL_VERSION" = "9.6" ]] ; then - - ## removing unused postgresql - #sudo apt-get -y remove --purge postgresql-9.1 - #sudo apt-get -y remove --purge postgresql-9.2 - #sudo apt-get -y remove --purge postgresql-9.3 - #sudo apt-get -y remove --purge postgresql-9.4 - #sudo apt-get -y remove --purge postgresql-9.5 - #sudo apt-get -y remove --purge postgresql-9.6 - - echo "Installing postgresql $POSTGRESQL_VERSION & postgis " - - sudo apt-get install -y \ - postgresql-$POSTGRESQL_VERSION \ - postgresql-$POSTGRESQL_VERSION-postgis-$POSTGIS_VERSION - - sudo cp /usr/lib/postgresql/$POSTGRESQL_VERSION/bin/pg_config /usr/bin/pg_config - - sudo /etc/init.d/postgresql stop - - - sudo cat /etc/postgresql/$POSTGRESQL_VERSION/main/pg_hba.conf - - sudo sed -i -e 's/port = 5433/port = 5432/g' /etc/postgresql/$POSTGRESQL_VERSION/main/postgresql.conf - sudo cp $TRAVIS_BUILD_DIR/ci/travis/pg_hba.conf /etc/postgresql/$POSTGRESQL_VERSION/main/pg_hba.conf - - ps -fea | grep postgres -fi - -sudo /etc/init.d/postgresql start $POSTGRESQL_VERSION - -# intall pgtap after postgres instance has started -sudo apt-get install -y postgresql-$POSTGRESQL_VERSION-pgtap -sudo apt-get install -y libtap-parser-sourcehandler-pgtap-perl diff --git a/ci/travis/osm2pgrouting_build.sh b/ci/travis/osm2pgrouting_build.sh deleted file mode 100755 index 997b0973..00000000 --- a/ci/travis/osm2pgrouting_build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# ------------------------------------------------------------------------------ -# Travis CI scripts -# Copyright(c) pgRouting Contributors -# -# Build pgRouting -# ------------------------------------------------------------------------------ - -# exit script on error -set -e - -# build osm2pgrouting -mkdir build -cd build -cmake .. -make -sudo make install -cd .. diff --git a/ci/travis/pg_hba.conf b/ci/travis/pg_hba.conf deleted file mode 100755 index 8326a376..00000000 --- a/ci/travis/pg_hba.conf +++ /dev/null @@ -1,12 +0,0 @@ -# PostgreSQL Client Authentication Configuration File -# =================================================== -# -# This file is configured to allow trusted authentication for Travis -# automated installation and tests. -# - -# Database administrative login by Unix domain socket -local all postgres trust -local all all trust -host all all 127.0.0.1/32 trust -host all all ::1/128 trust diff --git a/include/database/Export2DB.h b/include/database/Export2DB.h index 442e1ce1..1aca0aa4 100644 --- a/include/database/Export2DB.h +++ b/include/database/Export2DB.h @@ -49,9 +49,9 @@ class Export2DB { typedef std::vector Relations; /** - * Constructor + * Constructor * @param vm variable map holding the configuration - * @param db_conn conection string + * @param db_conn conection string * */ explicit Export2DB(const po::variables_map &vm, const std::string &db_conn); @@ -82,7 +82,7 @@ class Export2DB { * T.values * * @param[in] items vector of values to be inserted into - * @param[in] table + * @param[in] table */ template void export_osm ( @@ -120,6 +120,11 @@ class Export2DB { void process_section(const std::string &ways_columns, pqxx::work &Xaction) const; + void fill_adjacent_edges( + const std::string &table, + const std::string &vertices_tab, + pqxx::work &Xaction) const; + void fill_vertices_table( const std::string &table, const std::string &vertices_tab, diff --git a/include/database/table_management.h b/include/database/table_management.h index 18f06afb..faebd2e5 100644 --- a/include/database/table_management.h +++ b/include/database/table_management.h @@ -71,7 +71,7 @@ class Table { inline std::vector columns() const { return m_columns; } - std::string sql(int i) const {return m_sql[i];} + std::string sql(size_t i) const {return m_sql[i];} std::string tmp_create() const; diff --git a/include/osm_elements/OSMDocument.h b/include/osm_elements/OSMDocument.h index 4bb05e6d..d22ed76e 100644 --- a/include/osm_elements/OSMDocument.h +++ b/include/osm_elements/OSMDocument.h @@ -120,8 +120,8 @@ class OSMDocument { #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()); + auto start = residue? osm_items.size() - residue : osm_items.size() - m_chunk_size; + T export_items = T(osm_items.begin() + static_cast(start), osm_items.end()); m_db_conn.export_osm(export_items, table); diff --git a/include/parser/OSMDocumentParserCallback.h b/include/parser/OSMDocumentParserCallback.h index 1af0d0b7..3b0ab5d3 100644 --- a/include/parser/OSMDocumentParserCallback.h +++ b/include/parser/OSMDocumentParserCallback.h @@ -47,7 +47,6 @@ class OSMDocumentParserCallback : OSMDocument& m_rDocument; //! current way, which will be parsed // Way* m_pActWay; - Relation* m_pActRelation; virtual void StartElement(const char *name, const char** atts); @@ -59,11 +58,9 @@ class OSMDocumentParserCallback : */ explicit OSMDocumentParserCallback(OSMDocument& doc) : m_rDocument(doc), - m_pActRelation(0), last_node(nullptr), last_way(nullptr), last_relation(nullptr), - m_line(0), m_section(1) { } private: @@ -73,7 +70,6 @@ class OSMDocumentParserCallback : Node *last_node; Way *last_way; Relation* last_relation; - size_t m_line; int m_section; }; // class OSMDocumentParserCallback diff --git a/include/parser/XMLParser.h b/include/parser/XMLParser.h index ecef567a..5b655c07 100644 --- a/include/parser/XMLParser.h +++ b/include/parser/XMLParser.h @@ -28,7 +28,7 @@ namespace xml { /** - Callback to be used with XMLParser + Callback to be used with XMLParser */ class XMLParserCallback { public: @@ -40,10 +40,10 @@ class XMLParserCallback { /** Implement to construct an element with the given name, call back for parser event "start element" - + \param name [IN] element name \param atts [IN] the attributes - */ + */ virtual void StartElement(const char *name, const char** atts) = 0; /** @@ -53,11 +53,11 @@ class XMLParserCallback { }; /** - XML-Parser based on expat library by + XML-Parser based on expat library by James Clark http://www.jclark.com/xml/expat.html. - + Fast, event driven, non-validating parser - + Dependencies: - link with xmlparse.lib - uses xmlparse.dll @@ -71,17 +71,13 @@ class XMLParser { /** Parse a file from the file system- - + \param rCallback [IN] the parser callback - \param chFileName [IN] name of the file to be parsed - + \param chFileName [IN] name of the file to be parsed + \return 0: everything ok, 1: file not found, 2: parsing error - */ + */ int Parse(XMLParserCallback& rCallback, const char* chFileName); - - private: - //! the expat parser object / imported from „expat.h“ - XML_Parser m_ParserCtxt; }; } // end namespace xml diff --git a/mapconfig_for_pedestrian.xml b/mapconfig_for_pedestrian.xml index b1a37683..5ff9264e 100644 --- a/mapconfig_for_pedestrian.xml +++ b/mapconfig_for_pedestrian.xml @@ -25,5 +25,3 @@ - - diff --git a/src/database/Export2DB.cpp b/src/database/Export2DB.cpp index dfcf3d09..d5332efe 100644 --- a/src/database/Export2DB.cpp +++ b/src/database/Export2DB.cpp @@ -139,6 +139,8 @@ void Export2DB::createTables() const { if (!exists(ways().addSchema())) { Xaction.exec(ways().create()); + Xaction.exec("CREATE INDEX ON "+ ways().addSchema() + " USING btree (source)"); + Xaction.exec("CREATE INDEX ON "+ ways().addSchema() + " USING btree (target)"); std::cout << "TABLE: " << ways().addSchema() << " created ... OK.\n"; } @@ -269,7 +271,6 @@ Export2DB::export_osm( #endif - size_t count = 0; try { @@ -284,8 +285,6 @@ Export2DB::export_osm( for (auto it = values.begin(); it != values.end(); ++it) { auto str = *it; - ++count; - PQputline(mycon, str.c_str()); } @@ -302,9 +301,12 @@ Export2DB::export_osm( } return; } - size_t inc = values.size() / 2; - export_osm(std::vector(values.begin(), values.begin() + inc), table); - export_osm(std::vector(values.begin() + inc , values.end()), table); + + const int64_t inc = values.size() / 2; + std::vector first(values.begin(), values.begin() + inc); + std::vector second(values.begin() + inc, values.end()); + export_osm(first, table); + export_osm(second, table); return; }; @@ -337,13 +339,42 @@ void Export2DB::fill_vertices_table( ") , " " 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)"); + " INSERT INTO " + vertices_tab + " (osm_id, geom) (SELECT osm_id, 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_adjacent_edges( + const std::string &table, + const std::string &vertices_tab, + pqxx::work &Xaction) const { + std::string sql ( + "WITH " + " a AS (" + " SELECT v.id, array_agg(e.id) as outs FROM " + vertices_tab + " AS v join " + table + " AS e " + " ON (v.id = source) where cost > 0 GROUP BY v.id)" + "UPDATE " + vertices_tab + " AS v SET out_edges = outs FROM a WHERE v.id = a.id;"); + + auto result = Xaction.exec(sql); + std::cout << "\t out_edges modified: " << result.affected_rows(); + + sql = + "WITH " + " the_ins AS (" + " SELECT v.id, array_agg(e.id) as ins FROM " + vertices_tab + " AS v join " + table + " AS e " + " ON (v.id = target) where reverse_cost > 0 GROUP BY v.id)" + "UPDATE " + vertices_tab + " AS v SET in_edges = ins FROM the_ins AS a WHERE v.id = a.id;"; + + result = Xaction.exec(sql); + std::cout << "\t in_edges modified: " << result.affected_rows(); +} + + + + @@ -366,18 +397,21 @@ void Export2DB::fill_source_target( " WHERE w.target IS NULL and w.target_osm = v.osm_id;"); Xaction.exec(sql2); + sql2 = " UPDATE " + table + " SET length_m = ST_length(geography(geom)) WHERE length_m IS NULL;"; + Xaction.exec(sql2); + std::string sql3( " UPDATE " + table + - " SET length_m = ST_length(geography(ST_Transform(the_geom, 4326)))," + " SET " " 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)" + " WHEN one_way = -1 THEN -ST_length(geography(ST_Transform(geom, 4326))) / (maxspeed_forward::float * 5.0 / 18.0)" + " ELSE ST_length(geography(ST_Transform(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)" + " WHEN one_way = 1 THEN -ST_length(geography(ST_Transform(geom, 4326))) / (maxspeed_backward::float * 5.0 / 18.0)" + " ELSE ST_length(geography(ST_Transform(geom, 4326))) / (maxspeed_backward::float * 5.0 / 18.0)" " END " - " WHERE length_m IS NULL AND maxspeed_backward !=0 AND maxspeed_forward != 0;"); + " WHERE maxspeed_backward !=0 AND maxspeed_forward != 0;"); Xaction.exec(sql3); } @@ -400,7 +434,6 @@ void Export2DB::exportWays(const Ways &ways, const Configuration &config) const 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(); @@ -436,7 +469,6 @@ void Export2DB::exportWays(const Ways &ways, const Configuration &config) const 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]); @@ -490,7 +522,9 @@ void Export2DB::process_section(const std::string &ways_columns, pqxx::work &Xac // 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 "+ temp_table + "_gdx ON "+ temp_table + " using gist(geom);"); + Xaction.exec("CREATE INDEX ON "+ temp_table + " USING btree (source)"); + Xaction.exec("CREATE INDEX ON "+ temp_table + " USING btree (target)"); Xaction.exec("CREATE INDEX ON "+ temp_table + " USING btree (source_osm)"); Xaction.exec("CREATE INDEX ON "+ temp_table + " USING btree (target_osm)"); @@ -501,7 +535,7 @@ void Export2DB::process_section(const std::string &ways_columns, pqxx::work &Xac 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);"); + " WHERE a.geom ~= b.geom AND ST_OrderingEquals(a.geom, b.geom);"); Xaction.exec(delete_from_temp); // std::cout << "Updating to existing toplology the temporary table\n"; @@ -521,6 +555,7 @@ void Export2DB::process_section(const std::string &ways_columns, pqxx::work &Xac " (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"; + fill_adjacent_edges(ways().addSchema(), vertices().addSchema(), Xaction); } @@ -583,14 +618,12 @@ void Export2DB::createFKeys() const { /* * 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")); @@ -686,7 +719,7 @@ void Export2DB::process_pois() const { execute( "\n WITH " "\n base AS (" - "\n SELECT pid, w.id AS wid, w.the_geom AS wgeom, p.the_geom AS pgeom" + "\n SELECT pid, w.id AS wid, w.geom AS wgeom, p.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 )," diff --git a/src/database/ways_config.cpp b/src/database/edges_config.cpp similarity index 94% rename from src/database/ways_config.cpp rename to src/database/edges_config.cpp index 7b218711..b0f1c2fc 100644 --- a/src/database/ways_config.cpp +++ b/src/database/edges_config.cpp @@ -17,17 +17,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ +#include + #include "boost/lexical_cast.hpp" #include "database/table_management.h" #include "utilities/utilities.h" -#include namespace osm2pgr { /* - * configuring TABLE osm_nodes - */ + * configuring TABLE edges_pgr + */ Table @@ -47,8 +48,8 @@ Tables::ways_config() const { /* standard column creation string */ std::string( - " gid bigserial" - ", osm_id bigint" + " id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY" + ", osm_id BIGINT" ", tag_id integer" ", length double precision" @@ -75,6 +76,7 @@ Tables::ways_config() const { ", maxspeed_forward double precision" ", maxspeed_backward double precision" ", priority double precision DEFAULT 1" + ", geom GEOMETRY(LINESTRING, 4326)" #if 0 + (m_vm.count("attributes") ? (std::string(", attributes ") + (m_vm.count("hstore") ? "hstore" : "json")) @@ -89,8 +91,7 @@ Tables::ways_config() const { "", /* geometry */ - "LINESTRING"); - + ""); std::vector columns; columns.push_back("tag_id"); @@ -106,7 +107,7 @@ Tables::ways_config() const { 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("geom"); columns.push_back("cost"); columns.push_back("reverse_cost"); columns.push_back("name"); diff --git a/src/database/osm_nodes_config.cpp b/src/database/osm_nodes_config.cpp index 3ee053d5..a3b7409a 100644 --- a/src/database/osm_nodes_config.cpp +++ b/src/database/osm_nodes_config.cpp @@ -65,7 +65,7 @@ Tables::osm_nodes_config() const { "POINT"); std::vector columns; columns.push_back("osm_id"); - columns.push_back("the_geom"); + columns.push_back("geom"); // TODO get from the configuration columns.push_back("tag_name"); columns.push_back("tag_value"); diff --git a/src/database/osm_ways_config.cpp b/src/database/osm_ways_config.cpp index 1f6f6368..22d26048 100644 --- a/src/database/osm_ways_config.cpp +++ b/src/database/osm_ways_config.cpp @@ -77,7 +77,7 @@ Tables::osm_ways_config() const { // 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"); + columns.push_back("geom"); table.set_columns(columns); diff --git a/src/database/pois_config.cpp b/src/database/pois_config.cpp index 65b6653b..cb5cb0ad 100644 --- a/src/database/pois_config.cpp +++ b/src/database/pois_config.cpp @@ -72,7 +72,7 @@ Tables::pois_config() const { "POINT"); std::vector columns; columns.push_back("osm_id"); - columns.push_back("the_geom"); + columns.push_back("geom"); // TODO get from the configuration columns.push_back("tag_name"); columns.push_back("tag_value"); diff --git a/src/database/table_management.cpp b/src/database/table_management.cpp index 1a462154..b7b87925 100644 --- a/src/database/table_management.cpp +++ b/src/database/table_management.cpp @@ -47,7 +47,7 @@ Table::Table( std::string Table::gist_index() const { return "CREATE INDEX ON " + addSchema() - + "\n USING GIST (the_geom);"; + + "\n USING GIST (geom);"; } @@ -77,7 +77,7 @@ Table::primary_key(const std::string &column) const { -void +void Table::set_columns(const std::vector &columns) { m_columns = columns; } @@ -110,7 +110,7 @@ Table::create() const { sql += "SELECT AddGeometryColumn('" + m_schema + (m_schema == "" ? "" : "', '") - + table_name() + "', 'the_geom', 4326, '" + m_geometry + "', 2);"; + + table_name() + "', 'geom', 4326, '" + m_geometry + "', 2);"; if (name() == "pointsofinterest") { sql += "SELECT AddGeometryColumn('" @@ -134,8 +134,8 @@ Table::drop() const { std::string Table::temp_name() const { return - "__" - + table_name() + "__" + + table_name() + boost::lexical_cast(getpid()); } @@ -143,7 +143,7 @@ Table::temp_name() const { std::string Table::tmp_create() const { std::string sql = - "CREATE UNLOGGED TABLE " + "CREATE UNLOGGED TABLE " + temp_name() + " (" + m_create @@ -151,7 +151,7 @@ Table::tmp_create() const { + ");"; if (m_geometry != "") { sql += "SELECT AddGeometryColumn('" - + temp_name() + "', 'the_geom', 4326, '" + m_geometry + "', 2);"; + + temp_name() + "', 'geom', 4326, '" + m_geometry + "', 2);"; } return sql; } @@ -162,13 +162,13 @@ Tables::post_process(const Table &table) const { if (table.name() == "osm_nodes" || table.name() == "pointsofinterest" || table.name() == "osm_ways" - || table.name() == "osm_relations") { + || 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() + + " INSERT INTO " + table.addSchema() + "(" + comma_separated(table.columns()) + ") " + " (SELECT " + comma_separated(table.columns()) + " FROM data); "); return str; @@ -179,7 +179,7 @@ Tables::post_process(const Table &table) const { " 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() + + " INSERT INTO " + configuration().addSchema() + "(" + comma_separated(configuration().columns()) + ") " + " (SELECT " + comma_separated(configuration().columns()) + " FROM data); "); return str; @@ -256,8 +256,8 @@ Tables::Tables(const po::variables_map &vm) : "\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 SELECT ST_buffer(geom::geography, $1)::geometry AS bufferPois," + "\n ST_buffer(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))" @@ -265,20 +265,20 @@ Tables::Tables(const po::variables_map &vm) : +"\n )," +"\n pois AS (" +"\n SELECT * FROM " + pois().addSchema() + ", poi" - +"\n WHERE ST_Within(the_geom, bufferPois) " + +"\n WHERE ST_Within(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 WHERE ST_Intersects(geom, bufferWays)" +"\n )," +"\n first AS (" - +"\n SELECT ways.gid AS wid," + +"\n SELECT ways.id AS wid," +"\n source_osm, target_osm," - +"\n ST_distance(pois.the_geom::geography, ways.the_geom::geography) AS dist," + +"\n ST_distance(pois.geom::geography, ways.geom::geography) AS dist," +"\n pois.osm_id AS vid," - +"\n ST_linelocatepoint(ways.the_geom, pois.the_geom) AS fraction" + +"\n ST_linelocatepoint(ways.geom, pois.geom) AS fraction" +"\n FROM wayss AS ways , pois" +"\n WHERE pois.vertex_id IS NULL AND pois.edge_id IS NULL" +"\n )," @@ -318,8 +318,8 @@ Tables::Tables(const po::variables_map &vm) : "\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 SELECT pid, w.id AS wid, w.geom AS wgeom, p.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 AND side IS NULL" + "\n )," @@ -373,11 +373,11 @@ Tables::Tables(const po::variables_map &vm) : "\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 SET new_geom = ST_LineInterpolatePoint(e.geom, fraction)" + + "\n FROM " + ways().addSchema() + " AS e WHERE edge_id = e.id;" "\n UPDATE " + pois().addSchema() - + "\n SET new_geom = the_geom" + + "\n SET new_geom = geom" + "\n WHERE vertex_id IS NOT NULL;" + "\n $$" + "\n LANGUAGE sql;" diff --git a/src/database/ways_vertices_pgr_config.cpp b/src/database/vertices_config.cpp similarity index 82% rename from src/database/ways_vertices_pgr_config.cpp rename to src/database/vertices_config.cpp index 315ebb08..8b6b2fad 100644 --- a/src/database/ways_vertices_pgr_config.cpp +++ b/src/database/vertices_config.cpp @@ -26,10 +26,8 @@ namespace osm2pgr { /* - * configuring TABLE osm_nodes - */ - - + * configuring TABLE vertices_pgr + */ Table Tables::ways_vertices_pgr_config() const { Table table( @@ -48,14 +46,14 @@ Tables::ways_vertices_pgr_config() const { /* 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" + " id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY" + ", in_edges bigint[]" + ", out_edges bigint[]" + ", x decimal(11,8) GENERATED ALWAYS AS (ST_X(geom)) STORED" + ", y decimal(11,8) GENERATED ALWAYS AS (ST_Y(geom)) STORED" + ", osm_id BIGINT" + ", geom GEOMETRY(POINT, 4326)" + #if 0 + (m_vm.count("attributes") ? (std::string(", attributes ") + (m_vm.count("hstore") ? "hstore" : "json")) @@ -70,7 +68,7 @@ Tables::ways_vertices_pgr_config() const { "", /* geometry */ - "POINT"); + ""); return table; } diff --git a/src/osm_elements/OSMDocument.cpp b/src/osm_elements/OSMDocument.cpp index c187d222..1c076ac2 100644 --- a/src/osm_elements/OSMDocument.cpp +++ b/src/osm_elements/OSMDocument.cpp @@ -90,7 +90,7 @@ OSMDocument::AddNode(const Node &n) { m_nodes.push_back(n); } -void +void OSMDocument::AddWay(const Way &w) { if (m_ways.empty() && m_vm.count("addnodes")) { wait_child(); @@ -127,21 +127,21 @@ OSMDocument::AddRelation(const Relation &r) { void OSMDocument::endOfFile() { - + if (m_vm.count("addnodes") && m_waysPending) { m_waysPending = false; wait_child(); osm_table_export(m_ways, "osm_ways"); std::cout << "\nFinal osm_ways:\t\t" << m_ways.size(); } - + if (m_vm.count("addnodes") && m_relPending) { m_relPending = false; wait_child(); std::cout << "\nFinal osm_relations:\t" << m_relations.size() << "\n"; osm_table_export(m_relations, "osm_relations"); } - + std::cout << "\nEnd Of file\n\n\n"; } @@ -156,26 +156,28 @@ less(const T &item, const int64_t &id) { Node* OSMDocument::FindNode(int64_t node_id) { - auto it = std::lower_bound(m_nodes.begin(), m_nodes.end(), node_id, less); + auto it = std::lower_bound(m_nodes.begin(), m_nodes.end(), node_id, less); + if (it == m_nodes.end() || it->osm_id() != node_id) return nullptr; 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); - return (it != m_nodes.end()); + auto it = std::lower_bound(m_nodes.begin(), m_nodes.end(), node_id, less); + return (it != m_nodes.end() && it->osm_id() == node_id); } Way* OSMDocument::FindWay(int64_t way_id) { - auto it = std::lower_bound(m_ways.begin(), m_ways.end(), way_id, less); + auto it = std::lower_bound(m_ways.begin(), m_ways.end(), way_id, less); + if (it == m_ways.end() || it->osm_id() != way_id) return nullptr; 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); - return (it != m_ways.end()); + auto it = std::lower_bound(m_ways.begin(), m_ways.end(), way_id, less); + return (it != m_ways.end() && it->osm_id() == way_id); } void @@ -201,7 +203,7 @@ OSMDocument::add_node(Way &way, const char **atts) { /* * for example * - * + * * * And the configuration file has: * @@ -247,9 +249,8 @@ OSMDocument::export_pois() const { 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()); + auto start = residue? m_nodes.size() - residue : m_nodes.size() - m_chunk_size; + auto export_items = Nodes(m_nodes.begin() + static_cast(start), m_nodes.end()); /* * deleting nodes with no tag information */ diff --git a/src/osm_elements/Relation.cpp b/src/osm_elements/Relation.cpp index 35dc0322..da33aead 100644 --- a/src/osm_elements/Relation.cpp +++ b/src/osm_elements/Relation.cpp @@ -74,7 +74,8 @@ Relation::members_str() const { */ + "=>\"type=>way\","; } - way_list[way_list.size() -1] = ' '; + size_t n = way_list.size(); + if (n > 0) way_list.resize(n - 1); return way_list; } diff --git a/src/osm_elements/Way.cpp b/src/osm_elements/Way.cpp index b08797d2..b6464824 100644 --- a/src/osm_elements/Way.cpp +++ b/src/osm_elements/Way.cpp @@ -283,17 +283,18 @@ void Way::max_speed(const Tag &tag) { auto key = tag.key(); auto value = tag.value(); + auto get_val = [&](double a) {return (a >= 1.0) ? a : 50.0;}; if (key == "maxspeed:forward") { - m_maxspeed_forward = get_kph(value); + m_maxspeed_forward = get_val(get_kph(value)); return; } if (key == "maxspeed:backward") { - m_maxspeed_backward = get_kph(value); + m_maxspeed_backward = get_val(get_kph(value)); return; } if (key == "maxspeed") { - m_maxspeed_backward = get_kph(value); - m_maxspeed_forward = get_kph(value); + m_maxspeed_forward = get_val(get_kph(value)); + m_maxspeed_backward = get_val(get_kph(value)); return; } } diff --git a/src/osm_elements/osm2pgrouting.cpp b/src/osm_elements/osm2pgrouting.cpp index 0bc830a8..5a844c23 100644 --- a/src/osm_elements/osm2pgrouting.cpp +++ b/src/osm_elements/osm2pgrouting.cpp @@ -98,7 +98,7 @@ int main(int argc, char* argv[]) { } if (vm.count("version")) { - std::cout << "This is osm2pgrouting Version 2.3.9\n"; + std::cout << "This is osm2pgrouting Version 3.0.0\n"; return 0; } diff --git a/src/osm_elements/osm_element.cpp b/src/osm_elements/osm_element.cpp index c8e28b54..1d1c56cd 100644 --- a/src/osm_elements/osm_element.cpp +++ b/src/osm_elements/osm_element.cpp @@ -44,7 +44,7 @@ Element::Element(const char **atts) : } } -void +void Element::tag_config(const Tag &tag) { m_tag_config = tag; } @@ -154,7 +154,7 @@ getHstore(const std::map &values) { std::string hstore; if (values.empty()) return std::string(); - for (const auto item : values) { + for (const auto &item : values) { hstore += addquotes(item.first, true) + " => " @@ -172,7 +172,7 @@ getJSON(const std::map &values) { if (values.empty()) return std::string("{}"); std::string json("{"); for (const auto item : values) { - json += addquotes(item.first, true) + json += addquotes(item.first, true) + ":" + addquotes(item.second, true) + ","; } @@ -185,11 +185,11 @@ getJSON(const std::map &values) { std::vector Element::values(const std::vector &columns, bool is_hstore) const { std::vector values; - for (const auto column : columns) { - if (column == "osm_id" || column == "tag_id") { + for (const auto &column : columns) { + if (column == "osm_id" || column == "tag_id") { values.push_back(boost::lexical_cast(osm_id())); continue; - } + } if (column == "tag_name") { values.push_back(m_tag_config.key()); continue; @@ -198,7 +198,7 @@ Element::values(const std::vector &columns, bool is_hstore) const { values.push_back(m_tag_config.value()); continue; } - if (column == "the_geom") { + if (column == "geom") { values.push_back(get_geometry()); continue; } @@ -211,13 +211,13 @@ Element::values(const std::vector &columns, bool is_hstore) const { 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; diff --git a/src/parser/XMLParser.cpp b/src/parser/XMLParser.cpp index 5ece1d34..1503bdf9 100644 --- a/src/parser/XMLParser.cpp +++ b/src/parser/XMLParser.cpp @@ -21,8 +21,8 @@ #include "parser/XMLParser.h" -#include -#include +#include +#include #include #include @@ -82,7 +82,7 @@ int XMLParser::Parse(XMLParserCallback& rCallback, const char* chFileName) { fclose(fp); ret = 0; } else { - std::cerr << "Error opening " << chFileName << ":" << strerror(errno); + std::cerr << "Error opening " << chFileName << ":" << std::strerror(errno); } return ret; // return = 0 indicating success } diff --git a/src/utilities/utilities.cpp b/src/utilities/utilities.cpp index 0514bd45..0183ee11 100644 --- a/src/utilities/utilities.cpp +++ b/src/utilities/utilities.cpp @@ -20,6 +20,7 @@ #include #include +#include "boost/algorithm/string/replace.hpp" std::string @@ -39,6 +40,7 @@ tab_separated(const std::vector &columns) { if (column.empty() || column == "") { result += "\\N\t"; } else { + boost::replace_all(column, "\\", "\\\\"); result += column + "\t"; } }