diff --git a/.clang-tidy b/.clang-tidy index d1b047f3a..dbaf8536f 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -49,7 +49,6 @@ Checks: > -misc-unused-parameters, performance-*, -performance-noexcept-move-constructor, - -performance-move-const-arg, -performance-no-int-to-ptr, readability-*, -readability-avoid-const-params-in-decls, diff --git a/.github/workflows/osrm-backend.yml b/.github/workflows/osrm-backend.yml index d75b657cc..77ef71f19 100644 --- a/.github/workflows/osrm-backend.yml +++ b/.github/workflows/osrm-backend.yml @@ -68,12 +68,12 @@ jobs: ./scripts/format.sh && ./scripts/error_on_dirty.sh node ./scripts/validate_changelog.js npm run docs && ./scripts/error_on_dirty.sh - + docker-image: needs: format-taginfo-docs runs-on: ubuntu-22.04 continue-on-error: false - steps: + steps: - name: Check out the repo uses: actions/checkout@v3 - name: Enable osm.pbf cache @@ -85,7 +85,7 @@ jobs: v1-berlin-osm-pbf - name: Docker build run: | - docker build -t osrm-backend-local -f docker/Dockerfile . + docker build -t osrm-backend-local -f docker/Dockerfile . - name: Test Docker image run: | if [ ! -f "${PWD}/berlin-latest.osm.pbf" ]; then @@ -428,7 +428,7 @@ jobs: CXXCOMPILER: ${{ matrix.CXXCOMPILER }} CXXFLAGS: ${{ matrix.CXXFLAGS }} ENABLE_ASSERTIONS: ${{ matrix.ENABLE_ASSERTIONS }} - ENABLE_CLANG_TIDY: ${{ matrix.ENABLE_CLANG_TIDY }} + ENABLE_CLANG_TIDY: ${{ matrix.ENABLE_CLANG_TIDY }} ENABLE_COVERAGE: ${{ matrix.ENABLE_COVERAGE }} ENABLE_GLIBC_WORKAROUND: ${{ matrix.ENABLE_GLIBC_WORKAROUND }} ENABLE_CONAN: ${{ matrix.ENABLE_CONAN }} @@ -469,9 +469,9 @@ jobs: uses: actions/cache@v2 with: path: ${{github.workspace}}/test/cache - key: v2-test-${{ matrix.name }}-${{ github.sha }} + key: v3-test-${{ matrix.name }}-${{ github.sha }} restore-keys: | - v2-test-${{ matrix.name }}- + v3-test-${{ matrix.name }}- - name: Prepare environment run: | @@ -668,7 +668,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} ci-complete: - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 needs: [build-test-publish, docker-image, windows] steps: - run: echo "CI complete" diff --git a/CHANGELOG.md b/CHANGELOG.md index 850687ec9..f2d8b1e34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,23 @@ # Unreleased - Changes from 5.26.0 - API: + - CHANGED: Add `data_version` field to responses of all services. [#5387](https://github.com/Project-OSRM/osrm-backend/pull/5387) - FIXED: Use Boost.Beast to parse HTTP request. [#6294](https://github.com/Project-OSRM/osrm-backend/pull/6294) - FIXED: Fix inefficient osrm-routed connection handling [#6113](https://github.com/Project-OSRM/osrm-backend/pull/6113) + - NodeJS: + - FIXED: Support `skip_waypoints` in Node bindings [#6060](https://github.com/Project-OSRM/osrm-backend/pull/6060) - Misc: + - CHANGED: missing files list is included in exception message. [#5360](https://github.com/Project-OSRM/osrm-backend/pull/5360) - CHANGED: Do not use deprecated Callback::Call overload in Node bindings. [#6318](https://github.com/Project-OSRM/osrm-backend/pull/6318) - FIXED: Fix distance calculation consistency. [#6315](https://github.com/Project-OSRM/osrm-backend/pull/6315) - FIXED: Fix performance issue after migration to sol2 3.3.0. [#6304](https://github.com/Project-OSRM/osrm-backend/pull/6304) - CHANGED: Pass osm_node_ids by reference in osrm::updater::Updater class. [#6298](https://github.com/Project-OSRM/osrm-backend/pull/6298) - FIXED: Fix bug with reading Set values from Lua scripts. [#6285](https://github.com/Project-OSRM/osrm-backend/pull/6285) - FIXED: Bug in bicycle profile that caused exceptions if there is a highway=bicycle in the data. [#6296](https://github.com/Project-OSRM/osrm-backend/pull/6296) + - FIXED: Internal refactoring of identifier types used in data facade [#6044](https://github.com/Project-OSRM/osrm-backend/pull/6044) - Build: - CHANGED: Migrate to modern TBB version. [#6300](https://github.com/Project-OSRM/osrm-backend/pull/6300) + - CHANGED: Enable performance-move-const-arg clang-tidy check. [#6319](https://github.com/Project-OSRM/osrm-backend/pull/6319) - CHANGED: Use the latest node on CI. [#6317](https://github.com/Project-OSRM/osrm-backend/pull/6317) - CHANGED: Migrate Windows CI to GitHub Actions. [#6312](https://github.com/Project-OSRM/osrm-backend/pull/6312) - ADDED: Add smoke test for Docker image. [#6313](https://github.com/Project-OSRM/osrm-backend/pull/6313) @@ -34,6 +40,11 @@ - FIXED: Fixed Node docs generation check in CI. [#6058](https://github.com/Project-OSRM/osrm-backend/pull/6058) - CHANGED: Docker build, enabled arm64 build layer [#6172](https://github.com/Project-OSRM/osrm-backend/pull/6172) - CHANGED: Docker build, enabled apt-get update/install caching in separate layer for build phase [#6175](https://github.com/Project-OSRM/osrm-backend/pull/6175) + - FIXED: Bump CI complete meta job to ubuntu-20.04 [#6323](https://github.com/Project-OSRM/osrm-backend/pull/6323) + - Routing: + - CHANGED: Lazily generate optional route path data [#6045](https://github.com/Project-OSRM/osrm-backend/pull/6045) + - FIXED: Completed support for no_entry and no_exit turn restrictions. [#5988](https://github.com/Project-OSRM/osrm-backend/pull/5988) + - ADDED: Add support for non-round-trips with a single fixed endpoint. [#6050](https://github.com/Project-OSRM/osrm-backend/pull/6050) # 5.26.0 - Changes from 5.25.0 diff --git a/docs/http.md b/docs/http.md index 60149856b..acdc1cd4f 100644 --- a/docs/http.md +++ b/docs/http.md @@ -507,8 +507,8 @@ Right now, the following combinations are possible: | true | any | last | **yes** | | true | any | any | **yes** | | false | first | last | **yes** | -| false | first | any | no | -| false | any | last | no | +| false | first | any | **yes** | +| false | any | last | **yes** | | false | any | any | no | #### Example Requests diff --git a/features/car/restrictions.feature b/features/car/restrictions.feature index da76f4ded..b9c878b00 100644 --- a/features/car/restrictions.feature +++ b/features/car/restrictions.feature @@ -1008,3 +1008,123 @@ Feature: Car - Turn restrictions | from | to | route | | d | x | bd,abc,xa,xa | | d | z | bd,abc,cz,cz | + + + Scenario: Multiple restricted entrances + Given the node map + """ + b + | + a----e----c + | + d + """ + + And the ways + | nodes | + | ae | + | be | + | ce | + | de | + + And the relations + | type | way:from | way:to | node:via | restriction | + | restriction | ae,be | ed | e | no_entry | + + When I route I should get + | from | to | route | + | a | d | ae,ce,ce,de,de | + | b | d | be,ce,ce,de,de | + | c | d | ce,de,de | + + + Scenario: Multiple restricted exits + Given the node map + """ + b + | + a----e----c + | + d + """ + + And the ways + | nodes | + | ae | + | be | + | ce | + | de | + + And the relations + | type | way:from | way:to | node:via | restriction | + | restriction | ae | ce,de | e | no_exit | + + When I route I should get + | from | to | route | + | a | b | ae,be,be | + | a | c | ae,be,be,ce,ce | + | a | d | ae,be,be,de,de | + + + Scenario: Invalid restricted entrances/exits + Given the node map + """ + b + | + a----e----c + | + d + """ + + And the ways + | nodes | + | ae | + | be | + | ce | + | de | + + And the relations + | type | way:from | way:to | node:via | restriction | + | restriction | ae | ce,de | e | no_entry | + | restriction | ae,be | ed | e | no_exit | + + When I route I should get + | from | to | route | + | a | b | ae,be,be | + | a | c | ae,ce,ce | + | a | d | ae,de,de | + | b | d | be,de,de | + | c | d | ce,de,de | + + + Scenario: Invalid multi from/to restrictions + Given the node map + """ + b + | + a----e----c + | + d + """ + + And the ways + | nodes | + | ae | + | be | + | ce | + | de | + + And the relations + | type | way:from | way:to | node:via | restriction | + | restriction | ae,de | ce,de | e | no_right_turn | + | restriction | ae,be | ce,de | e | no_straight_on | + | restriction | ae,be | be,ce | e | only_left_turn | + | restriction | ae,be | ce,de | e | only_straight_on | + + When I route I should get + | from | to | route | + | a | b | ae,be,be | + | a | c | ae,ce,ce | + | a | d | ae,de,de | + | b | d | be,de,de | + | c | d | ce,de,de | diff --git a/features/nearest/pick.feature b/features/nearest/pick.feature index fb66ef654..dcdf5268c 100644 --- a/features/nearest/pick.feature +++ b/features/nearest/pick.feature @@ -59,6 +59,31 @@ Feature: Locating Nearest node on a Way - pick closest way | 3 | u | | 4 | w | + Scenario: Nearest - inside a oneway triangle + Given the node map + """ + c + + y z + 0 1 + 2 3 4 + a x u w b + """ + + And the ways + | nodes | oneway | + | ab | yes | + | bc | yes | + | ca | yes | + + When I request nearest I should get + | in | out | + | 0 | y | + | 1 | z | + | 2 | x | + | 3 | u | + | 4 | w | + Scenario: Nearest - High lat/lon Given the node locations | node | lat | lon | @@ -78,3 +103,30 @@ Feature: Locating Nearest node on a Way - pick closest way | x | a | | y | b | | z | c | + + Scenario: Nearest - data version + Given the node map + """ + c + + y z + 0 1 + 2 3 4 + a x u w b + """ + + And the ways + | nodes | + | ab | + | bc | + | ca | + + And the extract extra arguments "--data_version cucumber_data_version" + + When I request nearest I should get + | in | out | data_version | + | 0 | y | cucumber_data_version | + | 1 | z | cucumber_data_version | + | 2 | x | cucumber_data_version | + | 3 | u | cucumber_data_version | + | 4 | w | cucumber_data_version | diff --git a/features/step_definitions/matching.js b/features/step_definitions/matching.js index d7c62ee07..c8afa5838 100644 --- a/features/step_definitions/matching.js +++ b/features/step_definitions/matching.js @@ -117,6 +117,10 @@ module.exports = function () { got.duration = duration.toString(); } + if (headers.has('data_version')) { + got.data_version = json.data_version || ''; + } + // if header matches 'a:*', parse out the values for * // and return in that header headers.forEach((k) => { diff --git a/features/step_definitions/nearest.js b/features/step_definitions/nearest.js index ae4079b8d..49ec0775d 100644 --- a/features/step_definitions/nearest.js +++ b/features/step_definitions/nearest.js @@ -8,6 +8,7 @@ module.exports = function () { this.reprocessAndLoadData((e) => { if (e) return callback(e); var testRow = (row, ri, cb) => { + var inNode = this.findNodeByName(row.in); if (!inNode) throw new Error(util.format('*** unknown in-node "%s"', row.in)); @@ -17,6 +18,7 @@ module.exports = function () { this.requestNearest(inNode, this.queryParams, (err, response) => { if (err) return cb(err); var coord; + var headers = new Set(table.raw()[0]); if (response.statusCode === 200 && response.body.length) { var json = JSON.parse(response.body); @@ -25,6 +27,10 @@ module.exports = function () { var got = { in: row.in, out: row.out }; + if (headers.has('data_version')) { + got.data_version = json.data_version || ''; + } + Object.keys(row).forEach((key) => { if (key === 'out') { if (this.FuzzyMatch.matchLocation(coord, outNode)) { diff --git a/features/step_definitions/trip.js b/features/step_definitions/trip.js index e72044018..0efbc2259 100644 --- a/features/step_definitions/trip.js +++ b/features/step_definitions/trip.js @@ -43,6 +43,10 @@ module.exports = function () { got.message = json.message; } + if (headers.has('data_version')) { + got.data_version = json.data_version || ''; + } + if (headers.has('geometry')) { if (this.queryParams['geometries'] === 'polyline') { got.geometry = polyline.decode(json.trips[0].geometry).toString(); @@ -61,7 +65,8 @@ module.exports = function () { var subTrips; var trip_durations; var trip_distance; - if (res.statusCode === 200) { + var ok = res.statusCode === 200; + if (ok) { if (headers.has('trips')) { subTrips = json.trips.filter(t => !!t).map(t => t.legs).map(tl => Array.prototype.concat.apply([], tl.map((sl, i) => { var toAdd = []; @@ -84,8 +89,7 @@ module.exports = function () { } } - var ok = true, - encodedResult = ''; + var encodedResult = ''; if (json.trips) row.trips.split(',').forEach((sub, si) => { if (si >= subTrips.length) { diff --git a/features/testbot/distance_matrix.feature b/features/testbot/distance_matrix.feature index c1340146f..92f4b8a6a 100644 --- a/features/testbot/distance_matrix.feature +++ b/features/testbot/distance_matrix.feature @@ -726,4 +726,5 @@ Feature: Basic Distance Matrix | | 1 | 2 | 3 | | 1 | 0 | 1000.1 | 1400.1 | | 2 | 1000.1 | 0 | 400 | - | 3 | 1400.1 | 400 | 0 | \ No newline at end of file + | 3 | 1400.1 | 400 | 0 | + diff --git a/features/testbot/matching.feature b/features/testbot/matching.feature index f8e1b2738..2772ef03a 100644 --- a/features/testbot/matching.feature +++ b/features/testbot/matching.feature @@ -21,8 +21,27 @@ Feature: Basic Map Matching | abcd | no | When I match I should get - | trace | timestamps | matchings | - | ab1d | 0 1 2 3 | ad | + | trace | timestamps | matchings | data_version | + | ab1d | 0 1 2 3 | ad | | + + Scenario: Data_version test on matching + Given a grid size of 100 meters + Given the node map + """ + a b c d + + 1 + """ + + And the extract extra arguments "--data_version cucumber_data_version" + + And the ways + | nodes | oneway | + | abcd | no | + + When I match I should get + | trace | timestamps | matchings | data_version | + | ab1d | 0 1 2 3 | ad | cucumber_data_version | Scenario: Testbot - Map matching with trace splitting Given the node map @@ -792,4 +811,5 @@ Feature: Basic Map Matching When I match I should get | trace | geometry | a:distance | a:duration | a:weight | duration | | 2345 | 1.00018,1,1.000314,1 | 14.914666 | 1.4 | 1.4 | 1.4 | - | 4321 | 1.00027,1,1.000135,1 | 15.02597 | 1.5 | 1.5 | 1.5 | \ No newline at end of file + | 4321 | 1.00027,1,1.000135,1 | 15.02597 | 1.5 | 1.5 | 1.5 | + diff --git a/features/testbot/snap.feature b/features/testbot/snap.feature index 924e84f75..f9a6fff81 100644 --- a/features/testbot/snap.feature +++ b/features/testbot/snap.feature @@ -47,11 +47,31 @@ Feature: Snap start/end point to the nearest way | adb | When I route I should get - | from | to | route | - | 1 | b | adb,adb | - | 2 | b | adb,adb | - | 6 | b | aub,aub | - | 7 | b | aub,aub | + | from | to | route | data_version | + | 1 | b | adb,adb | | + | 2 | b | adb,adb | | + | 6 | b | aub,aub | | + | 7 | b | aub,aub | | + + Scenario: Data_version check on nearest + Given the node map + """ + 4 5 6 7 + 3 a u + 2 + 1 d b + """ + + And the extract extra arguments "--data_version cucumber_data_version" + + And the ways + | nodes | + | aub | + | adb | + + When I route I should get + | from | to | route | data_version | + | 1 | b | adb,adb | cucumber_data_version | Scenario: Snap to edge right under start/end point Given the node map @@ -182,4 +202,4 @@ Feature: Snap start/end point to the nearest way | x | m | xe,xe | | x | n | xf,xf | | x | o | xg,xg | - | x | p | xh,xh | \ No newline at end of file + | x | p | xh,xh | diff --git a/features/testbot/trip.feature b/features/testbot/trip.feature index 9fe3c23ae..531ccaa48 100644 --- a/features/testbot/trip.feature +++ b/features/testbot/trip.feature @@ -5,7 +5,7 @@ Feature: Basic trip planning Given the profile "testbot" Given a grid size of 10 meters - Scenario: Testbot - Trip: Roundtrip with one waypoint + Scenario: Testbot - Trip: Invalid options (like was in test suite for a long time) Given the node map """ a b @@ -20,8 +20,46 @@ Feature: Basic trip planning | da | When I plan a trip I should get - | waypoints | trips | - | a | aa | + | waypoints | trips | code | + | a | | InvalidOptions | + + Scenario: Testbot - Trip: Roundtrip between same waypoint + Given the node map + """ + a b + c d + """ + + And the ways + | nodes | + | ab | + | bc | + | cb | + | da | + + When I plan a trip I should get + | waypoints | trips | code | + | a,a | aa | Ok | + + Scenario: Testbot - Trip: data version check + Given the node map + """ + a b + c d + """ + + And the ways + | nodes | + | ab | + | bc | + | cb | + | da | + + And the extract extra arguments "--data_version cucumber_data_version" + + When I plan a trip I should get + | waypoints | trips | data_version | code | + | a,a | aa | cucumber_data_version | Ok | Scenario: Testbot - Trip: Roundtrip with waypoints (less than 10) Given the node map @@ -38,9 +76,9 @@ Feature: Basic trip planning | da | When I plan a trip I should get - | waypoints | trips | durations | - | a,b,c,d | abcda | 7.6 | - | d,b,c,a | dbcad | 7.6 | + | waypoints | trips | durations | code | + | a,b,c,d | abcda | 7.6 | Ok | + | d,b,c,a | dbcad | 7.6 | Ok | Scenario: Testbot - Trip: Roundtrip waypoints (more than 10) Given the node map @@ -69,36 +107,37 @@ Feature: Basic trip planning | waypoints | trips | | a,b,c,d,e,f,g,h,i,j,k,l | alkjihgfedcba | - Scenario: Testbot - Trip: Roundtrip FS waypoints (more than 10) - Given the node map - """ - a b c d - l e - k f - j i h g - """ - - And the ways - | nodes | - | ab | - | bc | - | de | - | ef | - | fg | - | gh | - | hi | - | ij | - | jk | - | kl | - | la | - - When I plan a trip I should get - | waypoints | source | trips | - | a,b,c,d,e,f,g,h,i,j,k,l | first | alkjihgfedcba | - - Scenario: Testbot - Trip: Roundtrip FE waypoints (more than 10) + Scenario: Testbot - Trip: FS waypoints (less than 10) Given the query options - | source | last | + | source | first | + Given the node map + """ + a b c d + l e + + j i g + """ + + And the ways + | nodes | + | ab | + | bc | + | de | + | eg | + | gi | + | ij | + | jl | + | la | + + When I plan a trip I should get + | waypoints | trips | roundtrip | durations | + | a,b,c,d,e,g,i,j,l | abcdegijla | true | 22 | + | a,b,c,d,e,g,i,j,l | abcljiged | false | 13 | + + + Scenario: Testbot - Trip: FS waypoints (more than 10) + Given the query options + | source | first | Given the node map """ a b c d @@ -122,8 +161,67 @@ Feature: Basic trip planning | la | When I plan a trip I should get - | waypoints | trips | - | a,b,c,d,e,f,g,h,i,j,k,l | lkjihgfedcbal | + | waypoints | trips | roundtrip | durations | + | a,b,c,d,e,f,g,h,i,j,k,l | alkjihgfedcba | true | 22 | + | a,b,c,d,e,f,g,h,i,j,k,l | acblkjihgfed | false | 13 | + + + Scenario: Testbot - Trip: FE waypoints (less than 10) + Given the query options + | destination | last | + Given the node map + """ + a b c d + l e + + j i g + """ + + And the ways + | nodes | + | ab | + | bc | + | de | + | eg | + | gi | + | ij | + | jl | + | la | + + When I plan a trip I should get + | waypoints | trips | roundtrip | durations | + | a,b,c,d,e,g,i,j,l | labcdegijl | true | 22 | + | a,b,c,d,e,g,i,j,l | degijabcl | false | 14 | + + Scenario: Testbot - Trip: FE waypoints (more than 10) + Given the query options + | destination | last | + Given the node map + """ + a b c d + l e + k f + j i h g + """ + + And the ways + | nodes | + | ab | + | bc | + | de | + | ef | + | fg | + | gh | + | hi | + | ij | + | jk | + | kl | + | la | + + When I plan a trip I should get + | waypoints | trips | roundtrip | durations | + | a,b,c,d,e,f,g,h,i,j,k,l | lkjihgfedcbal | true | 22 | + | a,b,c,d,e,f,g,h,i,j,k,l | cbakjihgfedl | false | 19 | Scenario: Testbot - Trip: Unroutable roundtrip with waypoints (less than 10) Given the node map @@ -274,7 +372,7 @@ Feature: Basic trip planning | a,b,d,e,c | first | last | true | abedca | - Scenario: Testbot - Trip: midway points in isoldated roads should return no trips + Scenario: Testbot - Trip: midway points in isolated roads should return no trips Given the node map """ a 1 b @@ -370,4 +468,4 @@ Feature: Basic trip planning When I plan a trip I should get | waypoints | trips | durations | geometry | | a,b,c,d | abcda | 7.6 | 1,1,1,1.00009,0.99991,1,1,1.00009,1,1,0.99991,1.00009,1,1 | - | d,b,c,a | dbcad | 7.6 | 0.99991,1.00009,1,1,1,1.00009,0.99991,1,1,1.00009,1,1,0.99991,1.00009 | \ No newline at end of file + | d,b,c,a | dbcad | 7.6 | 0.99991,1.00009,1,1,1,1.00009,0.99991,1,1,1.00009,1,1,0.99991,1.00009 | diff --git a/features/testbot/zero-speed-updates.feature b/features/testbot/zero-speed-updates.feature index c2bc82c94..ae5a99c7f 100644 --- a/features/testbot/zero-speed-updates.feature +++ b/features/testbot/zero-speed-updates.feature @@ -187,5 +187,5 @@ Feature: Check zero speed updates When I plan a trip I should get | waypoints | trips | code | - | a,b,c,d | abcda | NoTrips | - | d,b,c,a | dbcad | NoTrips | + | a,b,c,d | | NoTrips | + | d,b,c,a | | NoTrips | diff --git a/include/contractor/contract_excludable_graph.hpp b/include/contractor/contract_excludable_graph.hpp index 9d0cc6979..dbfe87da7 100644 --- a/include/contractor/contract_excludable_graph.hpp +++ b/include/contractor/contract_excludable_graph.hpp @@ -23,7 +23,7 @@ inline auto contractFullGraph(ContractorGraph contractor_graph, auto edges = toEdges(std::move(contractor_graph)); std::vector edge_filter(edges.size(), true); - return GraphAndFilter{QueryGraph{num_nodes, std::move(edges)}, {std::move(edge_filter)}}; + return GraphAndFilter{QueryGraph{num_nodes, edges}, {std::move(edge_filter)}}; } inline auto contractExcludableGraph(ContractorGraph contractor_graph_, @@ -91,7 +91,7 @@ inline auto contractExcludableGraph(ContractorGraph contractor_graph_, edge_container.Merge(toEdges(std::move(filtered_core_graph))); } - return GraphAndFilter{QueryGraph{num_nodes, std::move(edge_container.edges)}, + return GraphAndFilter{QueryGraph{num_nodes, edge_container.edges}, edge_container.MakeEdgeFilters()}; } } // namespace contractor diff --git a/include/contractor/query_edge.hpp b/include/contractor/query_edge.hpp index 351ecee24..1b42faae2 100644 --- a/include/contractor/query_edge.hpp +++ b/include/contractor/query_edge.hpp @@ -58,8 +58,8 @@ struct QueryEdge QueryEdge() : source(SPECIAL_NODEID), target(SPECIAL_NODEID) {} - QueryEdge(NodeID source, NodeID target, EdgeData data) - : source(source), target(target), data(std::move(data)) + QueryEdge(NodeID source, NodeID target, const EdgeData &data) + : source(source), target(target), data(data) { } diff --git a/include/engine/api/match_api.hpp b/include/engine/api/match_api.hpp index a93e49710..e95882f46 100644 --- a/include/engine/api/match_api.hpp +++ b/include/engine/api/match_api.hpp @@ -89,6 +89,11 @@ class MatchAPI final : public RouteAPI } response.values["matchings"] = std::move(routes); response.values["code"] = "Ok"; + auto data_timestamp = facade.GetTimestamp(); + if (!data_timestamp.empty()) + { + response.values["data_version"] = data_timestamp; + } } protected: diff --git a/include/engine/api/nearest_api.hpp b/include/engine/api/nearest_api.hpp index aff3c57dc..246cfe88c 100644 --- a/include/engine/api/nearest_api.hpp +++ b/include/engine/api/nearest_api.hpp @@ -116,6 +116,11 @@ class NearestAPI final : public BaseAPI } response.values["code"] = "Ok"; + auto data_timestamp = facade.GetTimestamp(); + if (!data_timestamp.empty()) + { + response.values["data_version"] = data_timestamp; + } } const NearestParameters ¶meters; diff --git a/include/engine/api/route_api.hpp b/include/engine/api/route_api.hpp index 72244c453..7b4dfc02f 100644 --- a/include/engine/api/route_api.hpp +++ b/include/engine/api/route_api.hpp @@ -367,7 +367,7 @@ class RouteAPI : public BaseAPI // To maintain support for uses of the old default constructors, we check // if annotations property was set manually after default construction auto requested_annotations = parameters.annotations_type; - if ((parameters.annotations == true) && + if (parameters.annotations && (parameters.annotations_type == RouteParameters::AnnotationsType::None)) { requested_annotations = RouteParameters::AnnotationsType::All; @@ -497,10 +497,10 @@ class RouteAPI : public BaseAPI std::vector nodes; if (requested_annotations & RouteParameters::AnnotationsType::Nodes) { - nodes.reserve(leg_geometry.osm_node_ids.size()); - for (const auto node_id : leg_geometry.osm_node_ids) + nodes.reserve(leg_geometry.node_ids.size()); + for (const auto node_id : leg_geometry.node_ids) { - nodes.emplace_back(static_cast(node_id)); + nodes.emplace_back(static_cast(facade.GetOSMNodeIDOfNode(node_id))); } } auto nodes_vector = fb_result.CreateVector(nodes); @@ -515,7 +515,7 @@ class RouteAPI : public BaseAPI { const auto name = facade.GetDatasourceName(i); // Length of 0 indicates the first empty name, so we can stop here - if (name.size() == 0) + if (name.empty()) break; names.emplace_back( fb_result.CreateString(std::string(facade.GetDatasourceName(i)))); @@ -763,7 +763,7 @@ class RouteAPI : public BaseAPI // To maintain support for uses of the old default constructors, we check // if annotations property was set manually after default construction auto requested_annotations = parameters.annotations_type; - if ((parameters.annotations == true) && + if (parameters.annotations && (parameters.annotations_type == RouteParameters::AnnotationsType::None)) { requested_annotations = RouteParameters::AnnotationsType::All; @@ -825,10 +825,11 @@ class RouteAPI : public BaseAPI if (requested_annotations & RouteParameters::AnnotationsType::Nodes) { util::json::Array nodes; - nodes.values.reserve(leg_geometry.osm_node_ids.size()); - for (const auto node_id : leg_geometry.osm_node_ids) + nodes.values.reserve(leg_geometry.node_ids.size()); + for (const auto node_id : leg_geometry.node_ids) { - nodes.values.push_back(static_cast(node_id)); + nodes.values.push_back( + static_cast(facade.GetOSMNodeIDOfNode(node_id))); } annotation.values["nodes"] = std::move(nodes); } @@ -842,7 +843,7 @@ class RouteAPI : public BaseAPI { const auto name = facade.GetDatasourceName(i); // Length of 0 indicates the first empty name, so we can stop here - if (name.size() == 0) + if (name.empty()) break; datasource_names.values.push_back(std::string(facade.GetDatasourceName(i))); } @@ -888,81 +889,92 @@ class RouteAPI : public BaseAPI const bool reversed_source = source_traversed_in_reverse[idx]; const bool reversed_target = target_traversed_in_reverse[idx]; - auto leg_geometry = guidance::assembleGeometry(BaseAPI::facade, - path_data, - phantoms.source_phantom, - phantoms.target_phantom, - reversed_source, - reversed_target); auto leg = guidance::assembleLeg(facade, path_data, - leg_geometry, phantoms.source_phantom, phantoms.target_phantom, - reversed_target, - parameters.steps); + reversed_target); - util::Log(logDEBUG) << "Assembling steps " << std::endl; - if (parameters.steps) + guidance::LegGeometry leg_geometry; + + // Generate additional geometry data if request includes turn-by-turn steps, + // overview geometry or route geometry annotations. + // Note that overview geometry and route geometry annotations can return different + // results depending on whether turn-by-turn steps are also requested. + if (parameters.steps || parameters.annotations || + parameters.overview != RouteParameters::OverviewType::False) { - auto steps = guidance::assembleSteps(BaseAPI::facade, - path_data, - leg_geometry, - phantoms.source_phantom, - phantoms.target_phantom, - reversed_source, - reversed_target); - // Apply maneuver overrides before any other post - // processing is performed - guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry); + leg_geometry = guidance::assembleGeometry(BaseAPI::facade, + path_data, + phantoms.source_phantom, + phantoms.target_phantom, + reversed_source, + reversed_target); - // Collapse segregated steps before others - steps = guidance::collapseSegregatedTurnInstructions(std::move(steps)); + util::Log(logDEBUG) << "Assembling steps " << std::endl; + if (parameters.steps) + { + leg.summary = guidance::assembleSummary( + facade, path_data, phantoms.target_phantom, reversed_target); - /* Perform step-based post-processing. - * - * Using post-processing on basis of route-steps for a single leg at a time - * comes at the cost that we cannot count the correct exit for roundabouts. - * We can only emit the exit nr/intersections up to/starting at a part of the leg. - * If a roundabout is not terminated in a leg, we will end up with a - *enter-roundabout - * and exit-roundabout-nr where the exit nr is out of sync with the previous enter. - * - * | S | - * * * - * ----* * ---- - * T - * ----* * ---- - * V * * - * | | - * | | - * - * Coming from S via V to T, we end up with the legs S->V and V->T. V-T will say to - *take - * the second exit, even though counting from S it would be the third. - * For S, we only emit `roundabout` without an exit number, showing that we enter a - *roundabout - * to find a via point. - * The same exit will be emitted, though, if we should start routing at S, making - * the overall response consistent. - * - * ⚠ CAUTION: order of post-processing steps is important - * - handleRoundabouts must be called before collapseTurnInstructions that - * expects post-processed roundabouts - */ + auto steps = guidance::assembleSteps(BaseAPI::facade, + path_data, + leg_geometry, + phantoms.source_phantom, + phantoms.target_phantom, + reversed_source, + reversed_target); - guidance::trimShortSegments(steps, leg_geometry); - leg.steps = guidance::handleRoundabouts(std::move(steps)); - leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps)); - leg.steps = guidance::anticipateLaneChange(std::move(leg.steps)); - leg.steps = guidance::buildIntersections(std::move(leg.steps)); - leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps)); - leg.steps = guidance::assignRelativeLocations(std::move(leg.steps), - leg_geometry, - phantoms.source_phantom, - phantoms.target_phantom); - leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps); + // Apply maneuver overrides before any other post + // processing is performed + guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry); + + // Collapse segregated steps before others + steps = guidance::collapseSegregatedTurnInstructions(std::move(steps)); + + /* Perform step-based post-processing. + * + * Using post-processing on basis of route-steps for a single leg at a time + * comes at the cost that we cannot count the correct exit for roundabouts. + * We can only emit the exit nr/intersections up to/starting at a part of the + *leg. If a roundabout is not terminated in a leg, we will end up with a + *enter-roundabout + * and exit-roundabout-nr where the exit nr is out of sync with the previous + *enter. + * + * | S | + * * * + * ----* * ---- + * T + * ----* * ---- + * V * * + * | | + * | | + * + * Coming from S via V to T, we end up with the legs S->V and V->T. V-T will say + *to take the second exit, even though counting from S it would be the third. + * For S, we only emit `roundabout` without an exit number, showing that we + *enter a roundabout to find a via point. The same exit will be emitted, though, + *if we should start routing at S, making the overall response consistent. + * + * ⚠ CAUTION: order of post-processing steps is important + * - handleRoundabouts must be called before collapseTurnInstructions that + * expects post-processed roundabouts + */ + + guidance::trimShortSegments(steps, leg_geometry); + leg.steps = guidance::handleRoundabouts(std::move(steps)); + leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps)); + leg.steps = guidance::anticipateLaneChange(std::move(leg.steps)); + leg.steps = guidance::buildIntersections(std::move(leg.steps)); + leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps)); + leg.steps = guidance::assignRelativeLocations(std::move(leg.steps), + leg_geometry, + phantoms.source_phantom, + phantoms.target_phantom); + leg_geometry = guidance::resyncGeometry(std::move(leg_geometry), leg.steps); + } } leg_geometries.push_back(std::move(leg_geometry)); diff --git a/include/engine/api/table_api.hpp b/include/engine/api/table_api.hpp index 72cdea4e6..2c378e6e7 100644 --- a/include/engine/api/table_api.hpp +++ b/include/engine/api/table_api.hpp @@ -226,6 +226,11 @@ class TableAPI final : public BaseAPI } response.values["code"] = "Ok"; + auto data_timestamp = facade.GetTimestamp(); + if (!data_timestamp.empty()) + { + response.values["data_version"] = data_timestamp; + } } protected: diff --git a/include/engine/api/trip_api.hpp b/include/engine/api/trip_api.hpp index 90e5e1391..9b82a016e 100644 --- a/include/engine/api/trip_api.hpp +++ b/include/engine/api/trip_api.hpp @@ -87,6 +87,11 @@ class TripAPI final : public RouteAPI } response.values["trips"] = std::move(routes); response.values["code"] = "Ok"; + auto data_timestamp = facade.GetTimestamp(); + if (!data_timestamp.empty()) + { + response.values["data_version"] = data_timestamp; + } } protected: diff --git a/include/engine/datafacade/algorithm_datafacade.hpp b/include/engine/datafacade/algorithm_datafacade.hpp index 38030511c..4ccbf5af3 100644 --- a/include/engine/datafacade/algorithm_datafacade.hpp +++ b/include/engine/datafacade/algorithm_datafacade.hpp @@ -36,24 +36,27 @@ template <> class AlgorithmDataFacade virtual unsigned GetNumberOfEdges() const = 0; - virtual unsigned GetOutDegree(const NodeID n) const = 0; + virtual unsigned GetOutDegree(const NodeID edge_based_node_id) const = 0; - virtual NodeID GetTarget(const EdgeID e) const = 0; + virtual NodeID GetTarget(const EdgeID edge_based_edge_id) const = 0; - virtual const EdgeData &GetEdgeData(const EdgeID e) const = 0; + virtual const EdgeData &GetEdgeData(const EdgeID edge_based_edge_id) const = 0; - virtual EdgeRange GetAdjacentEdgeRange(const NodeID node) const = 0; + virtual EdgeRange GetAdjacentEdgeRange(const NodeID edge_based_node_id) const = 0; // searches for a specific edge - virtual EdgeID FindEdge(const NodeID from, const NodeID to) const = 0; + virtual EdgeID FindEdge(const NodeID edge_based_node_from, + const NodeID edge_based_node_to) const = 0; - virtual EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const = 0; + virtual EdgeID FindEdgeInEitherDirection(const NodeID edge_based_node_from, + const NodeID edge_based_node_to) const = 0; - virtual EdgeID - FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const = 0; + virtual EdgeID FindEdgeIndicateIfReverse(const NodeID edge_based_node_from, + const NodeID edge_based_node_to, + bool &result) const = 0; - virtual EdgeID FindSmallestEdge(const NodeID from, - const NodeID to, + virtual EdgeID FindSmallestEdge(const NodeID edge_based_node_from, + const NodeID edge_based_node_to, const std::function filter) const = 0; }; @@ -70,23 +73,24 @@ template <> class AlgorithmDataFacade virtual unsigned GetNumberOfEdges() const = 0; - virtual unsigned GetOutDegree(const NodeID n) const = 0; + virtual unsigned GetOutDegree(const NodeID edge_based_node_id) const = 0; - virtual EdgeRange GetAdjacentEdgeRange(const NodeID node) const = 0; + virtual EdgeRange GetAdjacentEdgeRange(const NodeID edge_based_node_id) const = 0; - virtual EdgeWeight GetNodeWeight(const NodeID node) const = 0; + virtual EdgeWeight GetNodeWeight(const NodeID edge_based_node_id) const = 0; - virtual EdgeWeight GetNodeDuration(const NodeID node) const = 0; // TODO: to be removed + virtual EdgeWeight + GetNodeDuration(const NodeID edge_based_node_id) const = 0; // TODO: to be removed - virtual EdgeDistance GetNodeDistance(const NodeID node) const = 0; + virtual EdgeDistance GetNodeDistance(const NodeID edge_based_node_id) const = 0; - virtual bool IsForwardEdge(EdgeID edge) const = 0; + virtual bool IsForwardEdge(EdgeID edge_based_edge_id) const = 0; - virtual bool IsBackwardEdge(EdgeID edge) const = 0; + virtual bool IsBackwardEdge(EdgeID edge_based_edge_id) const = 0; - virtual NodeID GetTarget(const EdgeID e) const = 0; + virtual NodeID GetTarget(const EdgeID edge_based_edge_id) const = 0; - virtual const EdgeData &GetEdgeData(const EdgeID e) const = 0; + virtual const EdgeData &GetEdgeData(const EdgeID edge_based_edge_id) const = 0; virtual const partitioner::MultiLevelPartitionView &GetMultiLevelPartition() const = 0; @@ -94,10 +98,12 @@ template <> class AlgorithmDataFacade virtual const customizer::CellMetricView &GetCellMetric() const = 0; - virtual EdgeRange GetBorderEdgeRange(const LevelID level, const NodeID node) const = 0; + virtual EdgeRange GetBorderEdgeRange(const LevelID level, + const NodeID edge_based_node_id) const = 0; // searches for a specific edge - virtual EdgeID FindEdge(const NodeID from, const NodeID to) const = 0; + virtual EdgeID FindEdge(const NodeID edge_based_node_from, + const NodeID edge_based_node_to) const = 0; }; } // namespace datafacade } // namespace engine diff --git a/include/engine/datafacade/contiguous_internalmem_datafacade.hpp b/include/engine/datafacade/contiguous_internalmem_datafacade.hpp index e448a8f57..d426ed84f 100644 --- a/include/engine/datafacade/contiguous_internalmem_datafacade.hpp +++ b/include/engine/datafacade/contiguous_internalmem_datafacade.hpp @@ -73,45 +73,52 @@ class ContiguousInternalMemoryAlgorithmDataFacade : public datafacade::Algor unsigned GetNumberOfEdges() const override final { return m_query_graph.GetNumberOfEdges(); } - unsigned GetOutDegree(const NodeID n) const override final + unsigned GetOutDegree(const NodeID edge_based_node_id) const override final { - return m_query_graph.GetOutDegree(n); + return m_query_graph.GetOutDegree(edge_based_node_id); } - NodeID GetTarget(const EdgeID e) const override final { return m_query_graph.GetTarget(e); } - - const EdgeData &GetEdgeData(const EdgeID e) const override final + NodeID GetTarget(const EdgeID edge_based_edge_id) const override final { - return m_query_graph.GetEdgeData(e); + return m_query_graph.GetTarget(edge_based_edge_id); } - EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final + const EdgeData &GetEdgeData(const EdgeID edge_based_edge_id) const override final { - return m_query_graph.GetAdjacentEdgeRange(node); + return m_query_graph.GetEdgeData(edge_based_edge_id); + } + + EdgeRange GetAdjacentEdgeRange(const NodeID edge_based_node_id) const override final + { + return m_query_graph.GetAdjacentEdgeRange(edge_based_node_id); } // searches for a specific edge - EdgeID FindEdge(const NodeID from, const NodeID to) const override final + EdgeID FindEdge(const NodeID edge_based_node_from, + const NodeID edge_based_node_to) const override final { - return m_query_graph.FindEdge(from, to); + return m_query_graph.FindEdge(edge_based_node_from, edge_based_node_to); } - EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const override final + EdgeID FindEdgeInEitherDirection(const NodeID edge_based_node_from, + const NodeID edge_based_node_to) const override final { - return m_query_graph.FindEdgeInEitherDirection(from, to); + return m_query_graph.FindEdgeInEitherDirection(edge_based_node_from, edge_based_node_to); } - EdgeID - FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const override final + EdgeID FindEdgeIndicateIfReverse(const NodeID edge_based_node_from, + const NodeID edge_based_node_to, + bool &result) const override final { - return m_query_graph.FindEdgeIndicateIfReverse(from, to, result); + return m_query_graph.FindEdgeIndicateIfReverse( + edge_based_node_from, edge_based_node_to, result); } - EdgeID FindSmallestEdge(const NodeID from, - const NodeID to, + EdgeID FindSmallestEdge(const NodeID edge_based_node_from, + const NodeID edge_based_node_to, std::function filter) const override final { - return m_query_graph.FindSmallestEdge(from, to, filter); + return m_query_graph.FindSmallestEdge(edge_based_node_from, edge_based_node_to, filter); } }; @@ -126,11 +133,9 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade { private: using super = BaseDataFacade; - using IndexBlock = util::RangeTable<16, storage::Ownership::View>::BlockT; using RTreeLeaf = super::RTreeLeaf; using SharedRTree = util::StaticRTree; using SharedGeospatialQuery = GeospatialQuery; - using RTreeNode = SharedRTree::TreeNode; extractor::ClassData exclude_mask; extractor::ProfileProperties *m_profile_properties; @@ -231,76 +236,80 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade } // node and edge information access - util::Coordinate GetCoordinateOfNode(const NodeID id) const override final + util::Coordinate GetCoordinateOfNode(const NodeID node_based_node_id) const override final { - return m_coordinate_list[id]; + return m_coordinate_list[node_based_node_id]; } - OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const override final + OSMNodeID GetOSMNodeIDOfNode(const NodeID node_based_node_id) const override final { - return m_osmnodeid_list[id]; + return m_osmnodeid_list[node_based_node_id]; } - NodeForwardRange GetUncompressedForwardGeometry(const EdgeID id) const override final + NodeForwardRange GetUncompressedForwardGeometry(const PackedGeometryID id) const override final { return segment_data.GetForwardGeometry(id); } - NodeReverseRange GetUncompressedReverseGeometry(const EdgeID id) const override final + NodeReverseRange GetUncompressedReverseGeometry(const PackedGeometryID id) const override final { return segment_data.GetReverseGeometry(id); } - DurationForwardRange GetUncompressedForwardDurations(const EdgeID id) const override final + DurationForwardRange + GetUncompressedForwardDurations(const PackedGeometryID id) const override final { return segment_data.GetForwardDurations(id); } - DurationReverseRange GetUncompressedReverseDurations(const EdgeID id) const override final + DurationReverseRange + GetUncompressedReverseDurations(const PackedGeometryID id) const override final { return segment_data.GetReverseDurations(id); } - WeightForwardRange GetUncompressedForwardWeights(const EdgeID id) const override final + WeightForwardRange GetUncompressedForwardWeights(const PackedGeometryID id) const override final { return segment_data.GetForwardWeights(id); } - WeightReverseRange GetUncompressedReverseWeights(const EdgeID id) const override final + WeightReverseRange GetUncompressedReverseWeights(const PackedGeometryID id) const override final { return segment_data.GetReverseWeights(id); } // Returns the data source ids that were used to supply the edge // weights. - DatasourceForwardRange GetUncompressedForwardDatasources(const EdgeID id) const override final + DatasourceForwardRange + GetUncompressedForwardDatasources(const PackedGeometryID id) const override final { return segment_data.GetForwardDatasources(id); } // Returns the data source ids that were used to supply the edge // weights. - DatasourceReverseRange GetUncompressedReverseDatasources(const EdgeID id) const override final + DatasourceReverseRange + GetUncompressedReverseDatasources(const PackedGeometryID id) const override final { return segment_data.GetReverseDatasources(id); } - TurnPenalty GetWeightPenaltyForEdgeID(const EdgeID id) const override final + TurnPenalty GetWeightPenaltyForEdgeID(const EdgeID edge_based_edge_id) const override final { - BOOST_ASSERT(m_turn_weight_penalties.size() > id); - return m_turn_weight_penalties[id]; + BOOST_ASSERT(m_turn_weight_penalties.size() > edge_based_edge_id); + return m_turn_weight_penalties[edge_based_edge_id]; } - TurnPenalty GetDurationPenaltyForEdgeID(const EdgeID id) const override final + TurnPenalty GetDurationPenaltyForEdgeID(const EdgeID edge_based_edge_id) const override final { - BOOST_ASSERT(m_turn_duration_penalties.size() > id); - return m_turn_duration_penalties[id]; + BOOST_ASSERT(m_turn_duration_penalties.size() > edge_based_edge_id); + return m_turn_duration_penalties[edge_based_edge_id]; } osrm::guidance::TurnInstruction - GetTurnInstructionForEdgeID(const EdgeID id) const override final + GetTurnInstructionForEdgeID(const EdgeID edge_based_edge_id) const override final { - return turn_data.GetTurnInstruction(id); + return turn_data.GetTurnInstruction(edge_based_edge_id); } std::vector GetEdgesInBox(const util::Coordinate south_west, @@ -444,29 +453,29 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade return std::string(m_data_timestamp.begin(), m_data_timestamp.end()); } - GeometryID GetGeometryIndex(const NodeID id) const override final + GeometryID GetGeometryIndex(const NodeID edge_based_node_id) const override final { - return edge_based_node_data.GetGeometryID(id); + return edge_based_node_data.GetGeometryID(edge_based_node_id); } - ComponentID GetComponentID(const NodeID id) const override final + ComponentID GetComponentID(const NodeID edge_based_node_id) const override final { - return edge_based_node_data.GetComponentID(id); + return edge_based_node_data.GetComponentID(edge_based_node_id); } - extractor::TravelMode GetTravelMode(const NodeID id) const override final + extractor::TravelMode GetTravelMode(const NodeID edge_based_node_id) const override final { - return edge_based_node_data.GetTravelMode(id); + return edge_based_node_data.GetTravelMode(edge_based_node_id); } - extractor::ClassData GetClassData(const NodeID id) const override final + extractor::ClassData GetClassData(const NodeID edge_based_node_id) const override final { - return edge_based_node_data.GetClassData(id); + return edge_based_node_data.GetClassData(edge_based_node_id); } - bool ExcludeNode(const NodeID id) const override final + bool ExcludeNode(const NodeID edge_based_node_id) const override final { - return (edge_based_node_data.GetClassData(id) & exclude_mask) > 0; + return (edge_based_node_data.GetClassData(edge_based_node_id) & exclude_mask) > 0; } std::vector GetClasses(const extractor::ClassData class_data) const override final @@ -480,9 +489,9 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade return classes; } - NameID GetNameIndex(const NodeID id) const override final + NameID GetNameIndex(const NodeID edge_based_node_id) const override final { - return edge_based_node_data.GetNameID(id); + return edge_based_node_data.GetNameID(edge_based_node_id); } StringView GetNameForID(const NameID id) const override final @@ -537,32 +546,37 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade return m_profile_properties->GetWeightMultiplier(); } - util::guidance::BearingClass GetBearingClass(const NodeID node) const override final + util::guidance::BearingClass + GetBearingClass(const NodeID node_based_node_id) const override final { - return intersection_bearings_view.GetBearingClass(node); + return intersection_bearings_view.GetBearingClass(node_based_node_id); } - guidance::TurnBearing PreTurnBearing(const EdgeID eid) const override final + guidance::TurnBearing PreTurnBearing(const EdgeID edge_based_edge_id) const override final { - return turn_data.GetPreTurnBearing(eid); + return turn_data.GetPreTurnBearing(edge_based_edge_id); } - guidance::TurnBearing PostTurnBearing(const EdgeID eid) const override final + guidance::TurnBearing PostTurnBearing(const EdgeID edge_based_edge_id) const override final { - return turn_data.GetPostTurnBearing(eid); + return turn_data.GetPostTurnBearing(edge_based_edge_id); } - util::guidance::EntryClass GetEntryClass(const EdgeID turn_id) const override final + util::guidance::EntryClass GetEntryClass(const EdgeID edge_based_edge_id) const override final { - auto entry_class_id = turn_data.GetEntryClassID(turn_id); + auto entry_class_id = turn_data.GetEntryClassID(edge_based_edge_id); return m_entry_class_table.at(entry_class_id); } - bool HasLaneData(const EdgeID id) const override final { return turn_data.HasLaneData(id); } - - util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const override final + bool HasLaneData(const EdgeID edge_based_edge_id) const override final { - BOOST_ASSERT(HasLaneData(id)); - return m_lane_tupel_id_pairs.at(turn_data.GetLaneDataID(id)); + return turn_data.HasLaneData(edge_based_edge_id); + } + + util::guidance::LaneTupleIdPair + GetLaneData(const EdgeID edge_based_edge_id) const override final + { + BOOST_ASSERT(HasLaneData(edge_based_edge_id)); + return m_lane_tupel_id_pairs.at(turn_data.GetLaneDataID(edge_based_edge_id)); } extractor::TurnLaneDescription @@ -577,15 +591,15 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade m_lane_description_offsets[lane_description_id + 1]); } - bool IsLeftHandDriving(const NodeID id) const override final + bool IsLeftHandDriving(const NodeID edge_based_node_id) const override final { // TODO: can be moved to a data block indexed by GeometryID - return edge_based_node_data.IsLeftHandDriving(id); + return edge_based_node_data.IsLeftHandDriving(edge_based_node_id); } - bool IsSegregated(const NodeID id) const override final + bool IsSegregated(const NodeID edge_based_node_id) const override final { - return edge_based_node_data.IsSegregated(id); + return edge_based_node_data.IsSegregated(edge_based_node_id); } std::vector @@ -691,57 +705,62 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade : public Algo unsigned GetNumberOfEdges() const override final { return query_graph.GetNumberOfEdges(); } - unsigned GetOutDegree(const NodeID n) const override final + unsigned GetOutDegree(const NodeID edge_based_node_id) const override final { - return query_graph.GetOutDegree(n); + return query_graph.GetOutDegree(edge_based_node_id); } - EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final + EdgeRange GetAdjacentEdgeRange(const NodeID edge_based_node_id) const override final { - return query_graph.GetAdjacentEdgeRange(node); + return query_graph.GetAdjacentEdgeRange(edge_based_node_id); } - EdgeWeight GetNodeWeight(const NodeID node) const override final + EdgeWeight GetNodeWeight(const NodeID edge_based_node_id) const override final { - return query_graph.GetNodeWeight(node); + return query_graph.GetNodeWeight(edge_based_node_id); } - EdgeDuration GetNodeDuration(const NodeID node) const override final + EdgeDuration GetNodeDuration(const NodeID edge_based_node_id) const override final { - return query_graph.GetNodeDuration(node); + return query_graph.GetNodeDuration(edge_based_node_id); } - EdgeDistance GetNodeDistance(const NodeID node) const override final + EdgeDistance GetNodeDistance(const NodeID edge_based_node_id) const override final { - return query_graph.GetNodeDistance(node); + return query_graph.GetNodeDistance(edge_based_node_id); } - bool IsForwardEdge(const NodeID node) const override final + bool IsForwardEdge(const NodeID edge_based_node_id) const override final { - return query_graph.IsForwardEdge(node); + return query_graph.IsForwardEdge(edge_based_node_id); } - bool IsBackwardEdge(const NodeID node) const override final + bool IsBackwardEdge(const NodeID edge_based_node_id) const override final { - return query_graph.IsBackwardEdge(node); + return query_graph.IsBackwardEdge(edge_based_node_id); } - NodeID GetTarget(const EdgeID e) const override final { return query_graph.GetTarget(e); } - - const EdgeData &GetEdgeData(const EdgeID e) const override final + NodeID GetTarget(const EdgeID edge_based_edge_id) const override final { - return query_graph.GetEdgeData(e); + return query_graph.GetTarget(edge_based_edge_id); } - EdgeRange GetBorderEdgeRange(const LevelID level, const NodeID node) const override final + const EdgeData &GetEdgeData(const EdgeID edge_based_edge_id) const override final { - return query_graph.GetBorderEdgeRange(level, node); + return query_graph.GetEdgeData(edge_based_edge_id); + } + + EdgeRange GetBorderEdgeRange(const LevelID level, + const NodeID edge_based_node_id) const override final + { + return query_graph.GetBorderEdgeRange(level, edge_based_node_id); } // searches for a specific edge - EdgeID FindEdge(const NodeID from, const NodeID to) const override final + EdgeID FindEdge(const NodeID edge_based_node_from, + const NodeID edge_based_node_to) const override final { - return query_graph.FindEdge(from, to); + return query_graph.FindEdge(edge_based_node_from, edge_based_node_to); } }; diff --git a/include/engine/datafacade/datafacade_base.hpp b/include/engine/datafacade/datafacade_base.hpp index b80c93b18..153810fdd 100644 --- a/include/engine/datafacade/datafacade_base.hpp +++ b/include/engine/datafacade/datafacade_base.hpp @@ -77,46 +77,51 @@ class BaseDataFacade virtual std::string GetTimestamp() const = 0; // node and edge information access - virtual util::Coordinate GetCoordinateOfNode(const NodeID id) const = 0; + virtual util::Coordinate GetCoordinateOfNode(const NodeID node_based_node_id) const = 0; - virtual OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const = 0; + virtual OSMNodeID GetOSMNodeIDOfNode(const NodeID node_based_node_id) const = 0; - virtual GeometryID GetGeometryIndex(const NodeID id) const = 0; + virtual GeometryID GetGeometryIndex(const NodeID edge_based_node_id) const = 0; - virtual ComponentID GetComponentID(const NodeID id) const = 0; + virtual ComponentID GetComponentID(const NodeID edge_based_node_id) const = 0; - virtual NodeForwardRange GetUncompressedForwardGeometry(const EdgeID id) const = 0; - virtual NodeReverseRange GetUncompressedReverseGeometry(const EdgeID id) const = 0; + virtual NodeForwardRange GetUncompressedForwardGeometry(const PackedGeometryID id) const = 0; + virtual NodeReverseRange GetUncompressedReverseGeometry(const PackedGeometryID id) const = 0; - virtual TurnPenalty GetWeightPenaltyForEdgeID(const EdgeID id) const = 0; + virtual TurnPenalty GetWeightPenaltyForEdgeID(const EdgeID edge_based_edge_id) const = 0; - virtual TurnPenalty GetDurationPenaltyForEdgeID(const EdgeID id) const = 0; + virtual TurnPenalty GetDurationPenaltyForEdgeID(const EdgeID edge_based_edge_id) const = 0; // Gets the weight values for each segment in an uncompressed geometry. // Should always be 1 shorter than GetUncompressedGeometry - virtual WeightForwardRange GetUncompressedForwardWeights(const EdgeID id) const = 0; - virtual WeightReverseRange GetUncompressedReverseWeights(const EdgeID id) const = 0; + virtual WeightForwardRange GetUncompressedForwardWeights(const PackedGeometryID id) const = 0; + virtual WeightReverseRange GetUncompressedReverseWeights(const PackedGeometryID id) const = 0; // Gets the duration values for each segment in an uncompressed geometry. // Should always be 1 shorter than GetUncompressedGeometry - virtual DurationForwardRange GetUncompressedForwardDurations(const EdgeID id) const = 0; - virtual DurationReverseRange GetUncompressedReverseDurations(const EdgeID id) const = 0; + virtual DurationForwardRange + GetUncompressedForwardDurations(const PackedGeometryID id) const = 0; + virtual DurationReverseRange + GetUncompressedReverseDurations(const PackedGeometryID id) const = 0; // Returns the data source ids that were used to supply the edge // weights. Will return an empty array when only the base profile is used. - virtual DatasourceForwardRange GetUncompressedForwardDatasources(const EdgeID id) const = 0; - virtual DatasourceReverseRange GetUncompressedReverseDatasources(const EdgeID id) const = 0; + virtual DatasourceForwardRange + GetUncompressedForwardDatasources(const PackedGeometryID id) const = 0; + virtual DatasourceReverseRange + GetUncompressedReverseDatasources(const PackedGeometryID id) const = 0; // Gets the name of a datasource virtual StringView GetDatasourceName(const DatasourceID id) const = 0; - virtual osrm::guidance::TurnInstruction GetTurnInstructionForEdgeID(const EdgeID id) const = 0; + virtual osrm::guidance::TurnInstruction + GetTurnInstructionForEdgeID(const EdgeID edge_based_edge_id) const = 0; - virtual extractor::TravelMode GetTravelMode(const NodeID id) const = 0; + virtual extractor::TravelMode GetTravelMode(const NodeID edge_based_node_id) const = 0; - virtual extractor::ClassData GetClassData(const NodeID id) const = 0; + virtual extractor::ClassData GetClassData(const NodeID edge_based_node_id) const = 0; - virtual bool ExcludeNode(const NodeID id) const = 0; + virtual bool ExcludeNode(const NodeID edge_based_node_id) const = 0; virtual std::vector GetClasses(const extractor::ClassData class_data) const = 0; @@ -182,12 +187,12 @@ class BaseDataFacade const Approach approach, const bool use_all_edges = false) const = 0; - virtual bool HasLaneData(const EdgeID id) const = 0; - virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID id) const = 0; + virtual bool HasLaneData(const EdgeID edge_based_edge_id) const = 0; + virtual util::guidance::LaneTupleIdPair GetLaneData(const EdgeID edge_based_edge_id) const = 0; virtual extractor::TurnLaneDescription GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0; - virtual NameID GetNameIndex(const NodeID id) const = 0; + virtual NameID GetNameIndex(const NodeID edge_based_node_id) const = 0; virtual StringView GetNameForID(const NameID id) const = 0; @@ -209,16 +214,16 @@ class BaseDataFacade virtual double GetWeightMultiplier() const = 0; - virtual osrm::guidance::TurnBearing PreTurnBearing(const EdgeID eid) const = 0; - virtual osrm::guidance::TurnBearing PostTurnBearing(const EdgeID eid) const = 0; + virtual osrm::guidance::TurnBearing PreTurnBearing(const EdgeID edge_based_edge_id) const = 0; + virtual osrm::guidance::TurnBearing PostTurnBearing(const EdgeID edge_based_edge_id) const = 0; - virtual util::guidance::BearingClass GetBearingClass(const NodeID node) const = 0; + virtual util::guidance::BearingClass GetBearingClass(const NodeID node_based_node_id) const = 0; - virtual util::guidance::EntryClass GetEntryClass(const EdgeID turn_id) const = 0; + virtual util::guidance::EntryClass GetEntryClass(const EdgeID edge_based_edge_id) const = 0; - virtual bool IsLeftHandDriving(const NodeID id) const = 0; + virtual bool IsLeftHandDriving(const NodeID edge_based_node_id) const = 0; - virtual bool IsSegregated(const NodeID) const = 0; + virtual bool IsSegregated(const NodeID edge_based_node_id) const = 0; virtual std::vector GetOverridesThatStartAt(const NodeID edge_based_node_id) const = 0; diff --git a/include/engine/guidance/assemble_geometry.hpp b/include/engine/guidance/assemble_geometry.hpp index 736c868fd..88bb5e2d8 100644 --- a/include/engine/guidance/assemble_geometry.hpp +++ b/include/engine/guidance/assemble_geometry.hpp @@ -57,8 +57,7 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, const auto source_geometry_id = facade.GetGeometryIndex(source_node_id).id; const auto source_geometry = facade.GetUncompressedForwardGeometry(source_geometry_id); - geometry.osm_node_ids.push_back( - facade.GetOSMNodeIDOfNode(source_geometry(source_segment_start_coordinate))); + geometry.node_ids.push_back(source_geometry(source_segment_start_coordinate)); auto cumulative_distance = 0.; auto current_distance = 0.; @@ -71,7 +70,10 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, cumulative_distance += current_distance; // all changes to this check have to be matched with assemble_steps - if (path_point.turn_instruction.type != osrm::guidance::TurnType::NoTurn) + auto turn_instruction = path_point.turn_edge + ? facade.GetTurnInstructionForEdgeID(*path_point.turn_edge) + : osrm::guidance::TurnInstruction::NO_TURN(); + if (turn_instruction.type != osrm::guidance::TurnType::NoTurn) { geometry.segment_distances.push_back(cumulative_distance); geometry.segment_offsets.push_back(geometry.locations.size()); @@ -79,11 +81,10 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, } prev_coordinate = coordinate; + const auto node_id = path_point.turn_via_node; - const auto osm_node_id = facade.GetOSMNodeIDOfNode(path_point.turn_via_node); - - if (osm_node_id != geometry.osm_node_ids.back() || - path_point.turn_instruction.type != osrm::guidance::TurnType::NoTurn) + if (node_id != geometry.node_ids.back() || + turn_instruction.type != osrm::guidance::TurnType::NoTurn) { geometry.annotations.emplace_back(LegGeometry::Annotation{ current_distance, @@ -98,8 +99,8 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, (path_point.weight_until_turn - path_point.weight_of_turn) / facade.GetWeightMultiplier(), path_point.datasource_id}); - geometry.locations.push_back(std::move(coordinate)); - geometry.osm_node_ids.push_back(osm_node_id); + geometry.locations.push_back(coordinate); + geometry.node_ids.push_back(node_id); } } current_distance = @@ -158,8 +159,7 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, const auto target_segment_end_coordinate = target_node.fwd_segment_position + (reversed_target ? 0 : 1); const auto target_geometry = facade.GetUncompressedForwardGeometry(target_geometry_id); - geometry.osm_node_ids.push_back( - facade.GetOSMNodeIDOfNode(target_geometry(target_segment_end_coordinate))); + geometry.node_ids.push_back(target_geometry(target_segment_end_coordinate)); BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1); BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size()); diff --git a/include/engine/guidance/assemble_leg.hpp b/include/engine/guidance/assemble_leg.hpp index 0a49ae81e..617b317cf 100644 --- a/include/engine/guidance/assemble_leg.hpp +++ b/include/engine/guidance/assemble_leg.hpp @@ -75,10 +75,14 @@ std::array summarizeRoute(const datafacade::BaseDa std::vector segments(route_data.size()); std::uint32_t index = 0; - std::transform( - route_data.begin(), route_data.end(), segments.begin(), [&index](const PathData &point) { - return NamedSegment{point.duration_until_turn, index++, point.name_id}; - }); + std::transform(route_data.begin(), + route_data.end(), + segments.begin(), + [&index, &facade](const PathData &point) { + return NamedSegment{point.duration_until_turn, + index++, + facade.GetNameIndex(point.from_edge_based_node)}; + }); const auto target_duration = target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration; const auto target_node_id = target_traversed_in_reverse ? target_node.reverse_segment_id.id @@ -124,21 +128,59 @@ std::array summarizeRoute(const datafacade::BaseDa } } // namespace detail +inline std::string assembleSummary(const datafacade::BaseDataFacade &facade, + const std::vector &route_data, + const PhantomNode &target_node, + const bool target_traversed_in_reverse) +{ + auto summary_array = detail::summarizeRoute( + facade, route_data, target_node, target_traversed_in_reverse); + + BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0); + BOOST_ASSERT(summary_array.begin() != summary_array.end()); + + // transform a name_id into a string containing either the name, or -if the name is empty- + // the reference. + const auto name_id_to_string = [&](const NameID name_id) { + const auto name = facade.GetNameForID(name_id); + if (!name.empty()) + return name.to_string(); + else + { + const auto ref = facade.GetRefForID(name_id); + return ref.to_string(); + } + }; + + const auto not_empty = [&](const std::string &name) { return !name.empty(); }; + + const auto summary_names = summary_array | boost::adaptors::transformed(name_id_to_string) | + boost::adaptors::filtered(not_empty); + return boost::algorithm::join(summary_names, ", "); +} + inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade, const std::vector &route_data, - const LegGeometry &leg_geometry, const PhantomNode &source_node, const PhantomNode &target_node, - const bool target_traversed_in_reverse, - const bool needs_summary) + const bool target_traversed_in_reverse) { + auto distance = 0.; + auto prev_coordinate = source_node.location; + for (const auto &path_point : route_data) + { + auto coordinate = facade.GetCoordinateOfNode(path_point.turn_via_node); + distance += util::coordinate_calculation::greatCircleDistance(prev_coordinate, coordinate); + prev_coordinate = coordinate; + } + distance += + util::coordinate_calculation::greatCircleDistance(prev_coordinate, target_node.location); + const auto target_duration = (target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration); const auto target_weight = (target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight); - auto distance = std::accumulate( - leg_geometry.segment_distances.begin(), leg_geometry.segment_distances.end(), 0.); auto duration = std::accumulate( route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) { return sum + data.duration_until_turn; @@ -182,39 +224,10 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade, duration = std::max(0, duration); } - std::string summary; - if (needs_summary) - { - auto summary_array = detail::summarizeRoute( - facade, route_data, target_node, target_traversed_in_reverse); - - BOOST_ASSERT(detail::MAX_USED_SEGMENTS > 0); - BOOST_ASSERT(summary_array.begin() != summary_array.end()); - - // transform a name_id into a string containing either the name, or -if the name is empty- - // the reference. - const auto name_id_to_string = [&](const NameID name_id) { - const auto name = facade.GetNameForID(name_id); - if (!name.empty()) - return name.to_string(); - else - { - const auto ref = facade.GetRefForID(name_id); - return ref.to_string(); - } - }; - - const auto not_empty = [&](const std::string &name) { return !name.empty(); }; - - const auto summary_names = summary_array | boost::adaptors::transformed(name_id_to_string) | - boost::adaptors::filtered(not_empty); - summary = boost::algorithm::join(summary_names, ", "); - } - return RouteLeg{std::round(distance * 10.) / 10., duration / 10., weight / facade.GetWeightMultiplier(), - summary, + "", {}}; } diff --git a/include/engine/guidance/assemble_steps.hpp b/include/engine/guidance/assemble_steps.hpp index ac65a539f..97d527c7b 100644 --- a/include/engine/guidance/assemble_steps.hpp +++ b/include/engine/guidance/assemble_steps.hpp @@ -19,6 +19,7 @@ #include #include +#include #include namespace osrm @@ -96,7 +97,7 @@ inline std::vector assembleSteps(const datafacade::BaseDataFacade &fa {}, source_classes}; - if (leg_data.size() > 0) + if (!leg_data.empty()) { // PathData saves the information we need of the segment _before_ the turn, // but a RouteStep is with regard to the segment after the turn. @@ -115,7 +116,10 @@ inline std::vector assembleSteps(const datafacade::BaseDataFacade &fa segment_weight += path_point.weight_until_turn; // all changes to this check have to be matched with assemble_geometry - if (path_point.turn_instruction.type != osrm::guidance::TurnType::NoTurn) + const auto turn_instruction = + path_point.turn_edge ? facade.GetTurnInstructionForEdgeID(*path_point.turn_edge) + : osrm::guidance::TurnInstruction::NO_TURN(); + if (turn_instruction.type != osrm::guidance::TurnType::NoTurn) { BOOST_ASSERT(segment_weight >= 0); const auto name = facade.GetNameForID(step_name_id); @@ -125,7 +129,13 @@ inline std::vector assembleSteps(const datafacade::BaseDataFacade &fa const auto exits = facade.GetExitsForID(step_name_id); const auto distance = leg_geometry.segment_distances[segment_index]; // intersections contain the classes of exiting road - intersection.classes = facade.GetClasses(path_point.classes); + intersection.classes = + facade.GetClasses(facade.GetClassData(path_point.from_edge_based_node)); + + const auto is_left_hand_driving = + facade.IsLeftHandDriving(path_point.from_edge_based_node); + const auto travel_mode = facade.GetTravelMode(path_point.from_edge_based_node); + BOOST_ASSERT(travel_mode > 0); steps.push_back(RouteStep{path_point.from_edge_based_node, step_name_id, @@ -140,17 +150,19 @@ inline std::vector assembleSteps(const datafacade::BaseDataFacade &fa segment_duration / 10., distance, segment_weight / weight_multiplier, - path_point.travel_mode, + travel_mode, maneuver, leg_geometry.FrontIndex(segment_index), leg_geometry.BackIndex(segment_index) + 1, {intersection}, - path_point.is_left_hand_driving}); + is_left_hand_driving}); if (leg_data_index + 1 < leg_data.size()) { - step_name_id = leg_data[leg_data_index + 1].name_id; - is_segregated = leg_data[leg_data_index + 1].is_segregated; + step_name_id = + facade.GetNameIndex(leg_data[leg_data_index + 1].from_edge_based_node); + is_segregated = + facade.IsSegregated(leg_data[leg_data_index + 1].from_edge_based_node); } else { @@ -159,20 +171,33 @@ inline std::vector assembleSteps(const datafacade::BaseDataFacade &fa } // extract bearings - bearings = std::make_pair( - path_point.pre_turn_bearing.Get(), path_point.post_turn_bearing.Get()); + auto pre_turn_bearing = path_point.turn_edge + ? facade.PreTurnBearing(*path_point.turn_edge) + : osrm::guidance::TurnBearing(0); + auto post_turn_bearing = path_point.turn_edge + ? facade.PostTurnBearing(*path_point.turn_edge) + : osrm::guidance::TurnBearing(0); + bearings = std::make_pair(pre_turn_bearing.Get(), + post_turn_bearing.Get()); const auto bearing_class = facade.GetBearingClass(path_point.turn_via_node); auto bearing_data = bearing_class.getAvailableBearings(); + + util::guidance::LaneTupleIdPair lane_data = {{0, INVALID_LANEID}, + INVALID_LANE_DESCRIPTIONID}; + if (path_point.turn_edge && facade.HasLaneData(*path_point.turn_edge)) + { + lane_data = facade.GetLaneData(*path_point.turn_edge); + } + intersection.in = bearing_class.findMatchingBearing(bearings.first); intersection.out = bearing_class.findMatchingBearing(bearings.second); intersection.location = facade.GetCoordinateOfNode(path_point.turn_via_node); intersection.bearings.clear(); intersection.bearings.reserve(bearing_data.size()); - intersection.lanes = path_point.lane_data.first; - intersection.lane_description = - path_point.lane_data.second != INVALID_LANE_DESCRIPTIONID - ? facade.GetTurnDescription(path_point.lane_data.second) - : extractor::TurnLaneDescription(); + intersection.lanes = lane_data.first; + intersection.lane_description = lane_data.second != INVALID_LANE_DESCRIPTIONID + ? facade.GetTurnDescription(lane_data.second) + : extractor::TurnLaneDescription(); // Lanes in turn are bound by total number of lanes at the location BOOST_ASSERT(intersection.lanes.lanes_in_turn <= @@ -183,20 +208,23 @@ inline std::vector assembleSteps(const datafacade::BaseDataFacade &fa (!intersection.lane_description.empty() && intersection.lanes.lanes_in_turn != 0)); + auto entry_class = path_point.turn_edge + ? facade.GetEntryClass(*path_point.turn_edge) + : EMPTY_ENTRY_CLASS; std::copy(bearing_data.begin(), bearing_data.end(), std::back_inserter(intersection.bearings)); intersection.entry.clear(); for (auto idx : util::irange(0, intersection.bearings.size())) { - intersection.entry.push_back(path_point.entry_class.allowsEntry(idx)); + intersection.entry.push_back(entry_class.allowsEntry(idx)); } std::int16_t bearing_in_driving_direction = util::bearing::reverse(std::round(bearings.first)); maneuver = {intersection.location, bearing_in_driving_direction, bearings.second, - path_point.turn_instruction, + turn_instruction, WaypointType::None, 0}; segment_index++; @@ -269,7 +297,7 @@ inline std::vector assembleSteps(const datafacade::BaseDataFacade &fa leg_geometry.segment_distances[segment_index], weight / weight_multiplier, source_mode, - std::move(maneuver), + maneuver, leg_geometry.FrontIndex(segment_index), leg_geometry.BackIndex(segment_index) + 1, {intersection}, @@ -312,7 +340,7 @@ inline std::vector assembleSteps(const datafacade::BaseDataFacade &fa ZERO_DISTANCE, ZERO_WEIGHT, target_mode, - std::move(maneuver), + maneuver, leg_geometry.locations.size() - 1, leg_geometry.locations.size(), {intersection}, diff --git a/include/engine/guidance/leg_geometry.hpp b/include/engine/guidance/leg_geometry.hpp index 8374bb992..78ebd42ad 100644 --- a/include/engine/guidance/leg_geometry.hpp +++ b/include/engine/guidance/leg_geometry.hpp @@ -32,7 +32,7 @@ struct LegGeometry // length of the segment in meters std::vector segment_distances; // original OSM node IDs for each coordinate - std::vector osm_node_ids; + std::vector node_ids; // Per-coordinate metadata struct Annotation diff --git a/include/engine/internal_route_result.hpp b/include/engine/internal_route_result.hpp index 9f5443ffa..4ee80ab6a 100644 --- a/include/engine/internal_route_result.hpp +++ b/include/engine/internal_route_result.hpp @@ -15,6 +15,7 @@ #include "util/integer_range.hpp" #include "util/typedefs.hpp" +#include #include namespace osrm @@ -28,43 +29,22 @@ struct PathData NodeID from_edge_based_node; // the internal OSRM id of the OSM node id that is the via node of the turn NodeID turn_via_node; - // name of the street that leads to the turn - unsigned name_id; - // segregated edge-based node that leads to the turn - bool is_segregated; // weight that is traveled on the segment until the turn is reached // including the turn weight, if one exists EdgeWeight weight_until_turn; - // If this segment immediately preceeds a turn, then duration_of_turn + // If this segment immediately precedes a turn, then duration_of_turn // will contain the weight of the turn. Otherwise it will be 0. EdgeWeight weight_of_turn; // duration that is traveled on the segment until the turn is reached, - // including a turn if the segment preceeds one. + // including a turn if the segment precedes one. EdgeWeight duration_until_turn; - // If this segment immediately preceeds a turn, then duration_of_turn + // If this segment immediately precedes a turn, then duration_of_turn // will contain the duration of the turn. Otherwise it will be 0. EdgeWeight duration_of_turn; - // instruction to execute at the turn - osrm::guidance::TurnInstruction turn_instruction; - // turn lane data - util::guidance::LaneTupleIdPair lane_data; - // travel mode of the street that leads to the turn - extractor::TravelMode travel_mode : 4; - // user defined classed of the street that leads to the turn - extractor::ClassData classes; - // entry class of the turn, indicating possibility of turns - util::guidance::EntryClass entry_class; - // Source of the speed value on this road segment DatasourceID datasource_id; - - // bearing (as seen from the intersection) pre-turn - osrm::guidance::TurnBearing pre_turn_bearing; - // bearing (as seen from the intersection) post-turn - osrm::guidance::TurnBearing post_turn_bearing; - - // Driving side of the turn - bool is_left_hand_driving; + // If segment precedes a turn, ID of the turn itself + boost::optional turn_edge; }; struct InternalRouteResult diff --git a/include/engine/routing_algorithms/routing_base.hpp b/include/engine/routing_algorithms/routing_base.hpp index c7df59e80..59a0113fe 100644 --- a/include/engine/routing_algorithms/routing_base.hpp +++ b/include/engine/routing_algorithms/routing_base.hpp @@ -176,11 +176,6 @@ void annotatePath(const FacadeT &facade, const auto &edge_data = facade.GetEdgeData(*edge); const auto turn_id = edge_data.turn_id; // edge-based graph edge index const auto node_id = *node_from; // edge-based graph node index - const auto name_index = facade.GetNameIndex(node_id); - const bool is_segregated = facade.IsSegregated(node_id); - const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id); - const extractor::TravelMode travel_mode = facade.GetTravelMode(node_id); - const auto classes = facade.GetClassData(node_id); const auto geometry_index = facade.GetGeometryIndex(node_id); get_segment_geometry(geometry_index); @@ -206,45 +201,29 @@ void annotatePath(const FacadeT &facade, } const std::size_t end_index = weight_vector.size(); - bool is_left_hand_driving = facade.IsLeftHandDriving(node_id); - BOOST_ASSERT(start_index < end_index); for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx) { unpacked_path.push_back( - PathData{*node_from, + PathData{node_id, id_vector[segment_idx + 1], - name_index, - is_segregated, static_cast(weight_vector[segment_idx]), 0, static_cast(duration_vector[segment_idx]), 0, - guidance::TurnInstruction::NO_TURN(), - {{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID}, - travel_mode, - classes, - EMPTY_ENTRY_CLASS, datasource_vector[segment_idx], - osrm::guidance::TurnBearing(0), - osrm::guidance::TurnBearing(0), - is_left_hand_driving}); + boost::none}); } BOOST_ASSERT(unpacked_path.size() > 0); - if (facade.HasLaneData(turn_id)) - unpacked_path.back().lane_data = facade.GetLaneData(turn_id); const auto turn_duration = facade.GetDurationPenaltyForEdgeID(turn_id); const auto turn_weight = facade.GetWeightPenaltyForEdgeID(turn_id); - unpacked_path.back().entry_class = facade.GetEntryClass(turn_id); - unpacked_path.back().turn_instruction = turn_instruction; unpacked_path.back().duration_until_turn += turn_duration; unpacked_path.back().duration_of_turn = turn_duration; unpacked_path.back().weight_until_turn += turn_weight; unpacked_path.back().weight_of_turn = turn_weight; - unpacked_path.back().pre_turn_bearing = facade.PreTurnBearing(turn_id); - unpacked_path.back().post_turn_bearing = facade.PostTurnBearing(turn_id); + unpacked_path.back().turn_edge = turn_id; } std::size_t start_index = 0, end_index = 0; @@ -280,33 +259,22 @@ void annotatePath(const FacadeT &facade, // t: fwd_segment 3 // -> (U, v), (v, w), (w, x) // note that (x, t) is _not_ included but needs to be added later. - bool is_target_left_hand_driving = facade.IsLeftHandDriving(target_node_id); for (std::size_t segment_idx = start_index; segment_idx != end_index; (start_index < end_index ? ++segment_idx : --segment_idx)) { BOOST_ASSERT(segment_idx < static_cast(id_vector.size() - 1)); - BOOST_ASSERT(facade.GetTravelMode(target_node_id) > 0); unpacked_path.push_back( PathData{target_node_id, id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1], - facade.GetNameIndex(target_node_id), - facade.IsSegregated(target_node_id), static_cast(weight_vector[segment_idx]), 0, static_cast(duration_vector[segment_idx]), 0, - guidance::TurnInstruction::NO_TURN(), - {{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID}, - facade.GetTravelMode(target_node_id), - facade.GetClassData(target_node_id), - EMPTY_ENTRY_CLASS, datasource_vector[segment_idx], - guidance::TurnBearing(0), - guidance::TurnBearing(0), - is_target_left_hand_driving}); + boost::none}); } - if (unpacked_path.size() > 0) + if (!unpacked_path.empty()) { const auto source_weight = start_traversed_in_reverse ? phantom_node_pair.source_phantom.reverse_weight diff --git a/include/extractor/internal_extractor_edge.hpp b/include/extractor/internal_extractor_edge.hpp index c7ee904d9..032786c73 100644 --- a/include/extractor/internal_extractor_edge.hpp +++ b/include/extractor/internal_extractor_edge.hpp @@ -63,8 +63,8 @@ struct InternalExtractorEdge WeightData weight_data, DurationData duration_data, util::Coordinate source_coordinate) - : result(source, target, 0, 0, 0, {}, -1, {}), weight_data(std::move(weight_data)), - duration_data(std::move(duration_data)), source_coordinate(std::move(source_coordinate)) + : result(source, target, 0, 0, 0, {}, -1, {}), weight_data(weight_data), + duration_data(duration_data), source_coordinate(source_coordinate) { } @@ -72,7 +72,7 @@ struct InternalExtractorEdge WeightData weight_data, DurationData duration_data, util::Coordinate source_coordinate) - : result(std::move(edge)), weight_data(weight_data), duration_data(duration_data), + : result(edge), weight_data(weight_data), duration_data(duration_data), source_coordinate(source_coordinate) { } diff --git a/include/extractor/restriction_parser.hpp b/include/extractor/restriction_parser.hpp index 33367ae14..585396857 100644 --- a/include/extractor/restriction_parser.hpp +++ b/include/extractor/restriction_parser.hpp @@ -44,7 +44,7 @@ class RestrictionParser RestrictionParser(bool use_turn_restrictions, bool parse_conditionals, std::vector &restrictions); - boost::optional TryParse(const osmium::Relation &relation) const; + std::vector TryParse(const osmium::Relation &relation) const; private: bool ShouldIgnoreRestriction(const std::string &except_tag_string) const; diff --git a/include/nodejs/node_osrm_support.hpp b/include/nodejs/node_osrm_support.hpp index 400d420a5..25f96661d 100644 --- a/include/nodejs/node_osrm_support.hpp +++ b/include/nodejs/node_osrm_support.hpp @@ -675,6 +675,22 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo &arg params->generate_hints = Nan::To(generate_hints).FromJust(); } + if (Nan::Has(obj, Nan::New("skip_waypoints").ToLocalChecked()).FromJust()) + { + v8::Local skip_waypoints = + Nan::Get(obj, Nan::New("skip_waypoints").ToLocalChecked()).ToLocalChecked(); + if (skip_waypoints.IsEmpty()) + return false; + + if (!skip_waypoints->IsBoolean()) + { + Nan::ThrowError("skip_waypoints must be of type Boolean"); + return false; + } + + params->skip_waypoints = Nan::To(skip_waypoints).FromJust(); + } + if (Nan::Has(obj, Nan::New("exclude").ToLocalChecked()).FromJust()) { v8::Local exclude = diff --git a/include/partitioner/bisection_graph.hpp b/include/partitioner/bisection_graph.hpp index f0a5d62ff..e8dc80817 100644 --- a/include/partitioner/bisection_graph.hpp +++ b/include/partitioner/bisection_graph.hpp @@ -24,9 +24,10 @@ namespace partitioner // located at for use in the inertial flow sorting by slope. struct BisectionNode { - BisectionNode(util::Coordinate coordinate_ = {util::FloatLongitude{0}, util::FloatLatitude{0}}, + BisectionNode(const util::Coordinate &coordinate_ = {util::FloatLongitude{0}, + util::FloatLatitude{0}}, const NodeID original_id_ = SPECIAL_NODEID) - : coordinate(std::move(coordinate_)), original_id(original_id_) + : coordinate(coordinate_), original_id(original_id_) { } diff --git a/include/partitioner/edge_based_graph_reader.hpp b/include/partitioner/edge_based_graph_reader.hpp index 0c5d01b70..3a92dae5e 100644 --- a/include/partitioner/edge_based_graph_reader.hpp +++ b/include/partitioner/edge_based_graph_reader.hpp @@ -195,7 +195,7 @@ inline DynamicEdgeBasedGraph LoadEdgeBasedGraph(const boost::filesystem::path &p auto directed = splitBidirectionalEdges(edges); auto tidied = prepareEdgesForUsageInGraph(std::move(directed)); - return DynamicEdgeBasedGraph(number_of_edge_based_nodes, std::move(tidied), checksum); + return DynamicEdgeBasedGraph(number_of_edge_based_nodes, tidied, checksum); } } // namespace partitioner diff --git a/include/storage/io_config.hpp b/include/storage/io_config.hpp index 577291ee1..831382df7 100644 --- a/include/storage/io_config.hpp +++ b/include/storage/io_config.hpp @@ -25,6 +25,7 @@ struct IOConfig } bool IsValid() const; + std::vector GetMissingFiles() const; boost::filesystem::path GetPath(const std::string &fileName) const { if (!IsConfigured(fileName, required_input_files) && diff --git a/include/storage/shared_datatype.hpp b/include/storage/shared_datatype.hpp index bc4bf4efc..8ffb9bf24 100644 --- a/include/storage/shared_datatype.hpp +++ b/include/storage/shared_datatype.hpp @@ -59,7 +59,7 @@ class BaseDataLayout public: virtual ~BaseDataLayout() = default; - inline void SetBlock(const std::string &name, Block block) { blocks[name] = std::move(block); } + inline void SetBlock(const std::string &name, const Block &block) { blocks[name] = block; } inline std::uint64_t GetBlockEntries(const std::string &name) const { diff --git a/include/storage/view_factory.hpp b/include/storage/view_factory.hpp index 1153103b9..41ebf4283 100644 --- a/include/storage/view_factory.hpp +++ b/include/storage/view_factory.hpp @@ -77,7 +77,7 @@ inline auto make_name_table_view(const SharedDataIndex &index, const std::string auto values = make_vector_view(index, name + "/values"); - extractor::NameTableView::IndexedData index_data_view{std::move(blocks), std::move(values)}; + extractor::NameTableView::IndexedData index_data_view{blocks, values}; return extractor::NameTableView{index_data_view}; } @@ -156,14 +156,14 @@ inline auto make_segment_data_view(const SharedDataIndex &index, const std::stri auto rev_datasources_list = make_vector_view(index, name + "/reverse_data_sources"); - return extractor::SegmentDataView{std::move(geometry_begin_indices), - std::move(node_list), - std::move(fwd_weight_list), - std::move(rev_weight_list), - std::move(fwd_duration_list), - std::move(rev_duration_list), - std::move(fwd_datasources_list), - std::move(rev_datasources_list)}; + return extractor::SegmentDataView{geometry_begin_indices, + node_list, + fwd_weight_list, + rev_weight_list, + fwd_duration_list, + rev_duration_list, + fwd_datasources_list, + rev_datasources_list}; } inline auto make_coordinates_view(const SharedDataIndex &index, const std::string &name) @@ -214,7 +214,7 @@ inline auto make_search_tree_view(const SharedDataIndex &index, const std::strin } return util::StaticRTree{ - std::move(search_tree), std::move(rtree_level_starts), path, std::move(coordinates)}; + search_tree, rtree_level_starts, path, coordinates}; } inline auto make_intersection_bearings_view(const SharedDataIndex &index, const std::string &name) @@ -225,13 +225,11 @@ inline auto make_intersection_bearings_view(const SharedDataIndex &index, const index, name + "/class_id_to_ranges/diff_blocks"); auto bearing_values = make_vector_view(index, name + "/bearing_values"); util::RangeTable<16, storage::Ownership::View> bearing_range_table( - std::move(bearing_offsets), - std::move(bearing_blocks), - static_cast(bearing_values.size())); + bearing_offsets, bearing_blocks, static_cast(bearing_values.size())); auto bearing_class_id = make_vector_view(index, name + "/node_to_class_id"); return extractor::IntersectionBearingsView{ - std::move(bearing_values), std::move(bearing_class_id), std::move(bearing_range_table)}; + bearing_values, bearing_class_id, bearing_range_table}; } inline auto make_entry_classes_view(const SharedDataIndex &index, const std::string &name) @@ -252,8 +250,7 @@ inline auto make_contracted_metric_view(const SharedDataIndex &index, const std: edge_filter.push_back(make_vector_view(index, filter_name)); })); - return contractor::ContractedMetricView{{std::move(node_list), std::move(edge_list)}, - std::move(edge_filter)}; + return contractor::ContractedMetricView{{node_list, edge_list}, std::move(edge_filter)}; } inline auto make_partition_view(const SharedDataIndex &index, const std::string &name) @@ -264,8 +261,7 @@ inline auto make_partition_view(const SharedDataIndex &index, const std::string auto partition = make_vector_view(index, name + "/partition"); auto cell_to_children = make_vector_view(index, name + "/cell_to_children"); - return partitioner::MultiLevelPartitionView{ - level_data_ptr, std::move(partition), std::move(cell_to_children)}; + return partitioner::MultiLevelPartitionView{level_data_ptr, partition, cell_to_children}; } inline auto make_timestamp_view(const SharedDataIndex &index, const std::string &name) @@ -280,10 +276,8 @@ inline auto make_cell_storage_view(const SharedDataIndex &index, const std::stri auto cells = make_vector_view(index, name + "/cells"); auto level_offsets = make_vector_view(index, name + "/level_to_cell_offset"); - return partitioner::CellStorageView{std::move(source_boundary), - std::move(destination_boundary), - std::move(cells), - std::move(level_offsets)}; + return partitioner::CellStorageView{ + source_boundary, destination_boundary, cells, level_offsets}; } inline auto make_filtered_cell_metric_view(const SharedDataIndex &index, @@ -301,8 +295,7 @@ inline auto make_filtered_cell_metric_view(const SharedDataIndex &index, auto durations = make_vector_view(index, durations_block_id); auto distances = make_vector_view(index, distances_block_id); - return customizer::CellMetricView{ - std::move(weights), std::move(durations), std::move(distances)}; + return customizer::CellMetricView{weights, durations, distances}; } inline auto make_cell_metric_view(const SharedDataIndex &index, const std::string &name) @@ -321,8 +314,7 @@ inline auto make_cell_metric_view(const SharedDataIndex &index, const std::strin auto durations = make_vector_view(index, durations_block_id); auto distances = make_vector_view(index, distances_block_id); - cell_metric_excludes.push_back(customizer::CellMetricView{ - std::move(weights), std::move(durations), std::move(distances)}); + cell_metric_excludes.push_back(customizer::CellMetricView{weights, durations, distances}); } return cell_metric_excludes; @@ -342,14 +334,14 @@ inline auto make_multi_level_graph_view(const SharedDataIndex &index, const std: auto is_forward_edge = make_vector_view(index, name + "/is_forward_edge"); auto is_backward_edge = make_vector_view(index, name + "/is_backward_edge"); - return customizer::MultiLevelEdgeBasedGraphView(std::move(node_list), - std::move(edge_list), - std::move(node_to_offset), - std::move(node_weights), - std::move(node_durations), - std::move(node_distances), - std::move(is_forward_edge), - std::move(is_backward_edge)); + return customizer::MultiLevelEdgeBasedGraphView(node_list, + edge_list, + node_to_offset, + node_weights, + node_durations, + node_distances, + is_forward_edge, + is_backward_edge); } inline auto make_maneuver_overrides_views(const SharedDataIndex &index, const std::string &name) diff --git a/include/util/typedefs.hpp b/include/util/typedefs.hpp index 9868ee2ff..b1e962e2e 100644 --- a/include/util/typedefs.hpp +++ b/include/util/typedefs.hpp @@ -76,13 +76,13 @@ using NodeID = std::uint32_t; using EdgeID = std::uint32_t; using NameID = std::uint32_t; using AnnotationID = std::uint32_t; +using PackedGeometryID = std::uint32_t; using EdgeWeight = std::int32_t; using EdgeDuration = std::int32_t; using EdgeDistance = float; using SegmentWeight = std::uint32_t; using SegmentDuration = std::uint32_t; using TurnPenalty = std::int16_t; // turn penalty in 100ms units -using DataTimestamp = std::string; static const std::size_t INVALID_INDEX = std::numeric_limits::max(); @@ -95,16 +95,13 @@ static const LaneDescriptionID INVALID_LANE_DESCRIPTIONID = std::numeric_limits::max(); using BearingClassID = std::uint32_t; -static const BearingClassID INVALID_BEARING_CLASSID = std::numeric_limits::max(); - using DiscreteBearing = std::uint16_t; - using EntryClassID = std::uint16_t; -static const EntryClassID INVALID_ENTRY_CLASSID = std::numeric_limits::max(); static const NodeID SPECIAL_NODEID = std::numeric_limits::max(); static const NodeID SPECIAL_SEGMENTID = std::numeric_limits::max() >> 1; -static const NodeID SPECIAL_GEOMETRYID = std::numeric_limits::max() >> 1; +static const PackedGeometryID SPECIAL_GEOMETRYID = + std::numeric_limits::max() >> 1; static const EdgeID SPECIAL_EDGEID = std::numeric_limits::max(); static const RestrictionID SPECIAL_RESTRICTIONID = std::numeric_limits::max(); static const NameID INVALID_NAMEID = std::numeric_limits::max(); @@ -123,13 +120,6 @@ static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits::max(); static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits::max(); -// FIXME the bitfields we use require a reduced maximal duration, this should be kept consistent -// within the code base. For now we have to ensure that we don't case 30 bit to -1 and break any -// min() / operator< checks due to the invalid truncation. In addition, using signed and unsigned -// weights produces problems. As a result we can only store 1 << 29 since the MSB is still reserved -// for the sign bit. See https://github.com/Project-OSRM/osrm-backend/issues/3677 -static const EdgeWeight MAXIMAL_EDGE_DURATION_INT_30 = (1 << 29) - 1; - using DatasourceID = std::uint8_t; using BisectionID = std::uint32_t; @@ -158,11 +148,11 @@ struct SegmentID */ struct GeometryID { - GeometryID(const NodeID id_, const bool forward_) : id{id_}, forward{forward_} {} + GeometryID(const PackedGeometryID id_, const bool forward_) : id{id_}, forward{forward_} {} GeometryID() : id(std::numeric_limits::max() >> 1), forward(false) {} - NodeID id : 31; + PackedGeometryID id : 31; std::uint32_t forward : 1; }; diff --git a/src/contractor/contractor.cpp b/src/contractor/contractor.cpp index b98a22737..02703b0b1 100644 --- a/src/contractor/contractor.cpp +++ b/src/contractor/contractor.cpp @@ -105,7 +105,7 @@ int Contractor::Run() std::tie(query_graph, edge_filters) = contractExcludableGraph( toContractorGraph(number_of_edge_based_nodes, std::move(edge_based_edge_list)), std::move(node_weights), - std::move(node_filters)); + node_filters); TIMER_STOP(contraction); util::Log() << "Contracted graph has " << query_graph.GetNumberOfEdges() << " edges."; util::Log() << "Contraction took " << TIMER_SEC(contraction) << " sec"; diff --git a/src/customize/customizer.cpp b/src/customize/customizer.cpp index 38efef419..734bca590 100644 --- a/src/customize/customizer.cpp +++ b/src/customize/customizer.cpp @@ -92,8 +92,7 @@ auto LoadAndUpdateEdgeExpandedGraph(const CustomizationConfig &config, auto tidied = partitioner::prepareEdgesForUsageInGraph< typename partitioner::MultiLevelEdgeBasedGraph::InputEdge>(std::move(directed)); - auto edge_based_graph = - partitioner::MultiLevelEdgeBasedGraph(mlp, num_nodes, std::move(tidied)); + auto edge_based_graph = partitioner::MultiLevelEdgeBasedGraph(mlp, num_nodes, tidied); return edge_based_graph; } diff --git a/src/engine/guidance/post_processing.cpp b/src/engine/guidance/post_processing.cpp index f510e04b0..ac73e75b7 100644 --- a/src/engine/guidance/post_processing.cpp +++ b/src/engine/guidance/post_processing.cpp @@ -279,8 +279,7 @@ void trimShortSegments(std::vector &steps, LegGeometry &geometry) geometry.locations.begin() + offset); geometry.annotations.erase(geometry.annotations.begin(), geometry.annotations.begin() + offset); - geometry.osm_node_ids.erase(geometry.osm_node_ids.begin(), - geometry.osm_node_ids.begin() + offset); + geometry.node_ids.erase(geometry.node_ids.begin(), geometry.node_ids.begin() + offset); } auto const first_bearing = steps.front().maneuver.bearing_after; @@ -377,7 +376,7 @@ void trimShortSegments(std::vector &steps, LegGeometry &geometry) // remove all the last coordinates from the geometry geometry.locations.resize(geometry.segment_offsets.back() + 1); geometry.annotations.resize(geometry.segment_offsets.back()); - geometry.osm_node_ids.resize(geometry.segment_offsets.back() + 1); + geometry.node_ids.resize(geometry.segment_offsets.back() + 1); BOOST_ASSERT(geometry.segment_distances.back() <= 1); geometry.segment_distances.pop_back(); @@ -414,7 +413,7 @@ void trimShortSegments(std::vector &steps, LegGeometry &geometry) // This can happen if the last coordinate snaps to a node in the unpacked geometry geometry.locations.pop_back(); geometry.annotations.pop_back(); - geometry.osm_node_ids.pop_back(); + geometry.node_ids.pop_back(); geometry.segment_offsets.back()--; // since the last geometry includes the location of arrival, the arrival instruction // geometry overlaps with the previous segment @@ -436,7 +435,7 @@ void trimShortSegments(std::vector &steps, LegGeometry &geometry) } BOOST_ASSERT(geometry.segment_offsets.back() + 1 == geometry.locations.size()); - BOOST_ASSERT(geometry.segment_offsets.back() + 1 == geometry.osm_node_ids.size()); + BOOST_ASSERT(geometry.segment_offsets.back() + 1 == geometry.node_ids.size()); BOOST_ASSERT(geometry.segment_offsets.back() == geometry.annotations.size()); BOOST_ASSERT(steps.back().geometry_end == geometry.locations.size()); @@ -541,7 +540,7 @@ std::vector buildIntersections(std::vector steps) { // End of road is a turn that helps to identify the location of a turn. If the turn does - // not pass by any oter intersections, the end-of-road characteristic does not improve + // not pass by any other intersections, the end-of-road characteristic does not improve // the instructions. // Here we reduce the verbosity of our output by reducing end-of-road emissions in cases // where no intersections have been passed in between. diff --git a/src/engine/plugins/trip.cpp b/src/engine/plugins/trip.cpp index d949fcb60..20daf95d9 100644 --- a/src/engine/plugins/trip.cpp +++ b/src/engine/plugins/trip.cpp @@ -36,18 +36,7 @@ bool IsSupportedParameterCombination(const bool fixed_start, const bool fixed_end, const bool roundtrip) { - if (fixed_start && fixed_end && !roundtrip) - { - return true; - } - else if (roundtrip) - { - return true; - } - else - { - return false; - } + return roundtrip || fixed_start || fixed_end; } // given the node order in which to visit, compute the actual route (with geometry, travel time and @@ -142,6 +131,32 @@ void ManipulateTableForFSE(const std::size_t source_id, //********* End of changes to table ************************************* } +void ManipulateTableForNonRoundtripFS(const std::size_t source_id, + util::DistTableWrapper &result_table) +{ + // We can use the round-trip calculation to simulate non-round-trip fixed start + // by making all paths to the source location zero. Effectively finding an 'optimal' + // round-trip path that ignores the cost of getting back from any destination to the + // source. + for (const auto i : util::irange(0, result_table.GetNumberOfNodes())) + { + result_table.SetValue(i, source_id, 0); + } +} + +void ManipulateTableForNonRoundtripFE(const std::size_t destination_id, + util::DistTableWrapper &result_table) +{ + // We can use the round-trip calculation to simulate non-round-trip fixed end + // by making all paths from the destination to other locations zero. + // Effectively, finding an 'optimal' round-trip path that ignores the cost of getting + // from the destination to any source. + for (const auto i : util::irange(0, result_table.GetNumberOfNodes())) + { + result_table.SetValue(destination_id, i, 0); + } +} + Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, const api::TripParameters ¶meters, osrm::engine::api::ResultT &result) const @@ -225,7 +240,7 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, return Status::Error; } - const constexpr std::size_t BF_MAX_FEASABLE = 10; + const constexpr std::size_t BF_MAX_FEASIBLE = 10; BOOST_ASSERT_MSG(result_duration_table.size() == number_of_locations * number_of_locations, "Distance Table has wrong size"); @@ -238,11 +253,19 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, { ManipulateTableForFSE(source_id, destination_id, result_duration_table); } + else if (!parameters.roundtrip && fixed_start) + { + ManipulateTableForNonRoundtripFS(source_id, result_duration_table); + } + else if (!parameters.roundtrip && fixed_end) + { + ManipulateTableForNonRoundtripFE(destination_id, result_duration_table); + } std::vector duration_trip; duration_trip.reserve(number_of_locations); // get an optimized order in which the destinations should be visited - if (number_of_locations < BF_MAX_FEASABLE) + if (number_of_locations < BF_MAX_FEASIBLE) { duration_trip = trip::BruteForceTrip(number_of_locations, result_duration_table); } @@ -251,20 +274,28 @@ Status TripPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, duration_trip = trip::FarthestInsertionTrip(number_of_locations, result_duration_table); } - // rotate result such that roundtrip starts at node with index 0 - // thist first if covers scenarios: !fixed_end || fixed_start || (fixed_start && fixed_end) if (!fixed_end || fixed_start) { + // rotate result such that trip starts at node with index 0 auto desired_start_index = std::find(std::begin(duration_trip), std::end(duration_trip), 0); BOOST_ASSERT(desired_start_index != std::end(duration_trip)); std::rotate(std::begin(duration_trip), desired_start_index, std::end(duration_trip)); } - else if (fixed_end && !fixed_start && parameters.roundtrip) - { - auto desired_start_index = + else + { // fixed_end + auto destination_index = std::find(std::begin(duration_trip), std::end(duration_trip), destination_id); - BOOST_ASSERT(desired_start_index != std::end(duration_trip)); - std::rotate(std::begin(duration_trip), desired_start_index, std::end(duration_trip)); + BOOST_ASSERT(destination_index != std::end(duration_trip)); + if (!parameters.roundtrip) + { + // We want the location after destination to be at the front + std::advance(destination_index, 1); + if (destination_index == std::end(duration_trip)) + { + destination_index = std::begin(duration_trip); + } + } + std::rotate(std::begin(duration_trip), destination_index, std::end(duration_trip)); } // get the route when visiting all destinations in optimized order diff --git a/src/engine/routing_algorithms/alternative_path_mld.cpp b/src/engine/routing_algorithms/alternative_path_mld.cpp index 96329c27f..c22419c67 100644 --- a/src/engine/routing_algorithms/alternative_path_mld.cpp +++ b/src/engine/routing_algorithms/alternative_path_mld.cpp @@ -851,7 +851,7 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData &sear const auto extract_packed_path_from_heaps = [&](WeightedViaNode via) { auto packed_path = retrievePackedPathFromHeap(forward_heap, reverse_heap, via.node); - return WeightedViaNodePackedPath{std::move(via), std::move(packed_path)}; + return WeightedViaNodePackedPath{via, std::move(packed_path)}; }; std::vector weighted_packed_paths; diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index ec0675936..439621955 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -71,7 +71,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( const extractor::LaneDescriptionMap &lane_description_map) : m_edge_based_node_container(node_data_container), m_connectivity_checksum(0), m_number_of_edge_based_nodes(0), m_coordinates(coordinates), - m_node_based_graph(std::move(node_based_graph)), m_barrier_nodes(barrier_nodes), + m_node_based_graph(node_based_graph), m_barrier_nodes(barrier_nodes), m_traffic_lights(traffic_lights), m_compressed_edge_container(compressed_edge_container), name_table(name_table), segregated_edges(segregated_edges), lane_description_map(lane_description_map) diff --git a/src/extractor/extraction_containers.cpp b/src/extractor/extraction_containers.cpp index 24d7b5e76..e498e1001 100644 --- a/src/extractor/extraction_containers.cpp +++ b/src/extractor/extraction_containers.cpp @@ -276,7 +276,7 @@ void ExtractionContainers::PrepareNodes() continue; } BOOST_ASSERT(node_iter->node_id == *ref_iter); - *used_nodes_iter = std::move(*ref_iter); + *used_nodes_iter = *ref_iter; used_nodes_iter++; node_iter++; ref_iter++; diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index 9ac6db0c6..6ecfe83e5 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -380,7 +380,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti parsed_way.pronunciation, parsed_way.exits}; auto v = MapVal{name_id}; - string_map.emplace(std::move(k), std::move(v)); + string_map.emplace(std::move(k), v); } else { @@ -441,8 +441,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti parsed_way.highway_turn_classification, parsed_way.access_turn_classification}}; - external_memory.all_edges_list.push_back(InternalExtractorEdge( - std::move(edge), forward_weight_data, forward_duration_data, {})); + external_memory.all_edges_list.push_back( + InternalExtractorEdge(edge, forward_weight_data, forward_duration_data, {})); }); } @@ -475,8 +475,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti parsed_way.highway_turn_classification, parsed_way.access_turn_classification}}; - external_memory.all_edges_list.push_back(InternalExtractorEdge( - std::move(edge), backward_weight_data, backward_duration_data, {})); + external_memory.all_edges_list.push_back( + InternalExtractorEdge(edge, backward_weight_data, backward_duration_data, {})); }); } diff --git a/src/extractor/restriction_parser.cpp b/src/extractor/restriction_parser.cpp index c81f4331d..a135214f5 100644 --- a/src/extractor/restriction_parser.cpp +++ b/src/extractor/restriction_parser.cpp @@ -50,13 +50,13 @@ RestrictionParser::RestrictionParser(bool use_turn_restrictions_, * in the corresponding profile. We use it for both namespacing restrictions, as in * restriction:motorcar as well as whitelisting if its in except:motorcar. */ -boost::optional +std::vector RestrictionParser::TryParse(const osmium::Relation &relation) const { // return if turn restrictions should be ignored if (!use_turn_restrictions) { - return boost::none; + return {}; } osmium::tags::KeyFilter filter(false); @@ -85,17 +85,19 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const // if it's not a restriction, continue; if (std::distance(fi_begin, fi_end) == 0) { - return boost::none; + return {}; } // check if the restriction should be ignored const char *except = relation.get_value_by_key("except"); if (except != nullptr && ShouldIgnoreRestriction(except)) { - return boost::none; + return {}; } bool is_only_restriction = false; + bool is_multi_from = false; + bool is_multi_to = false; for (; fi_begin != fi_end; ++fi_begin) { @@ -111,21 +113,26 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const else if (value.find("no_") == 0 && !boost::algorithm::ends_with(value, "_on_red")) { is_only_restriction = false; + if (boost::algorithm::starts_with(value, "no_exit")) + { + is_multi_to = true; + } + else if (boost::algorithm::starts_with(value, "no_entry")) + { + is_multi_from = true; + } } else // unrecognized value type { - return boost::none; + return {}; } } - InputTurnRestriction restriction_container; - restriction_container.is_only = is_only_restriction; - constexpr auto INVALID_OSM_ID = std::numeric_limits::max(); - auto from = INVALID_OSM_ID; + std::vector from_ways; auto via_node = INVALID_OSM_ID; std::vector via_ways; - auto to = INVALID_OSM_ID; + std::vector to_ways; bool is_node_restriction = true; for (const auto &member : relation.members()) @@ -157,11 +164,11 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const 0 == strcmp("via", role)); if (0 == strcmp("from", role)) { - from = static_cast(member.ref()); + from_ways.push_back({static_cast(member.ref())}); } else if (0 == strcmp("to", role)) { - to = static_cast(member.ref()); + to_ways.push_back({static_cast(member.ref())}); } else if (0 == strcmp("via", role)) { @@ -178,6 +185,7 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const } } + std::vector condition; // parse conditional tags if (parse_conditionals) { @@ -199,32 +207,54 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const std::vector hours = util::ParseOpeningHours(p.condition); // found unrecognized condition, continue if (hours.empty()) - return boost::none; + return {}; - restriction_container.condition = std::move(hours); + condition = std::move(hours); } } } - if (from != INVALID_OSM_ID && (via_node != INVALID_OSM_ID || !via_ways.empty()) && - to != INVALID_OSM_ID) + std::vector restriction_containers; + if (!from_ways.empty() && (via_node != INVALID_OSM_ID || !via_ways.empty()) && !to_ways.empty()) { - if (is_node_restriction) + if (from_ways.size() > 1 && !is_multi_from) { - // template struct requires bracket for ID initialisation :( - restriction_container.node_or_way = InputNodeRestriction{{from}, {via_node}, {to}}; + util::Log(logDEBUG) << "Parsed restriction " << relation.id() + << " unexpectedly contains " << from_ways.size() + << " from ways, skipping..."; + return {}; } - else + if (to_ways.size() > 1 && !is_multi_to) { - // template struct requires bracket for ID initialisation :( - restriction_container.node_or_way = InputWayRestriction{{from}, via_ways, {to}}; + util::Log(logDEBUG) << "Parsed restriction " << relation.id() + << " unexpectedly contains " << to_ways.size() + << " to ways, skipping..."; + return {}; + } + // Internally restrictions are represented with one 'from' and one 'to' way. + // Therefore we need to convert a multi from/to restriction into multiple restrictions. + for (const auto &from : from_ways) + { + for (const auto &to : to_ways) + { + InputTurnRestriction restriction; + restriction.is_only = is_only_restriction; + restriction.condition = condition; + if (is_node_restriction) + { + // template struct requires bracket for ID initialisation :( + restriction.node_or_way = InputNodeRestriction{{from}, {via_node}, {to}}; + } + else + { + // template struct requires bracket for ID initialisation :( + restriction.node_or_way = InputWayRestriction{{from}, via_ways, {to}}; + } + restriction_containers.push_back(std::move(restriction)); + } } - return restriction_container; - } - else - { - return boost::none; } + return restriction_containers; } bool RestrictionParser::ShouldIgnoreRestriction(const std::string &except_tag_string) const diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index 2d0978d51..744140022 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -909,13 +909,15 @@ void Sol2ScriptingEnvironment::ProcessElements( case osmium::item_type::relation: { const auto &relation = static_cast(*entity); - if (auto result_res = restriction_parser.TryParse(relation)) + auto results = restriction_parser.TryParse(relation); + if (!results.empty()) { - resulting_restrictions.push_back(*result_res); + std::move( + results.begin(), results.end(), std::back_inserter(resulting_restrictions)); } else if (auto result_res = maneuver_override_parser.TryParse(relation)) { - resulting_maneuver_overrides.push_back(*result_res); + resulting_maneuver_overrides.push_back(std::move(*result_res)); } } break; diff --git a/src/osrm/osrm.cpp b/src/osrm/osrm.cpp index 8871aff45..83e1076f7 100644 --- a/src/osrm/osrm.cpp +++ b/src/osrm/osrm.cpp @@ -10,6 +10,8 @@ #include "engine/engine_config.hpp" #include "engine/status.hpp" +#include + #include namespace osrm @@ -25,8 +27,11 @@ OSRM::OSRM(engine::EngineConfig &config) // First, check that necessary core data is available if (!config.use_shared_memory && !config.storage_config.IsValid()) { - throw util::exception("Required files are missing, cannot continue. Have all the " - "pre-processing steps been run?"); + const auto &missingFiles = config.storage_config.GetMissingFiles(); + throw util::exception("Required files are missing, cannot continue. Have all the " + "pre-processing steps been run? " + "Missing files: " + + boost::algorithm::join(missingFiles, ", ")); } // Now, check that the algorithm requested can be used with the data diff --git a/src/partitioner/inertial_flow.cpp b/src/partitioner/inertial_flow.cpp index 59a4aceb4..0d8aa425f 100644 --- a/src/partitioner/inertial_flow.cpp +++ b/src/partitioner/inertial_flow.cpp @@ -38,8 +38,8 @@ makeSpatialOrder(const BisectionGraphView &view, const double ratio, const doubl { struct NodeWithCoordinate { - NodeWithCoordinate(NodeID nid_, util::Coordinate coordinate_) - : nid{nid_}, coordinate{std::move(coordinate_)} + NodeWithCoordinate(NodeID nid_, const util::Coordinate &coordinate_) + : nid{nid_}, coordinate{coordinate_} { } diff --git a/src/partitioner/recursive_bisection.cpp b/src/partitioner/recursive_bisection.cpp index 85d478923..27a8f70ac 100644 --- a/src/partitioner/recursive_bisection.cpp +++ b/src/partitioner/recursive_bisection.cpp @@ -86,13 +86,13 @@ RecursiveBisection::RecursiveBisection(BisectionGraph &bisection_graph_, TreeNode left_node{std::move(left_graph), node.depth + 1}; if (!terminal(left_node)) - feeder.add(std::move(left_node)); + feeder.add(left_node); BisectionGraphView right_graph{bisection_graph, center, node.graph.End()}; TreeNode right_node{std::move(right_graph), node.depth + 1}; if (!terminal(right_node)) - feeder.add(std::move(right_node)); + feeder.add(right_node); }); TIMER_STOP(bisection); diff --git a/src/storage/io_config.cpp b/src/storage/io_config.cpp index e100a9317..cd05d2d76 100644 --- a/src/storage/io_config.cpp +++ b/src/storage/io_config.cpp @@ -10,10 +10,11 @@ namespace osrm { namespace storage { + +namespace fs = boost::filesystem; + bool IOConfig::IsValid() const { - namespace fs = boost::filesystem; - bool success = true; for (auto &fileName : required_input_files) { @@ -26,5 +27,18 @@ bool IOConfig::IsValid() const } return success; } + +std::vector IOConfig::GetMissingFiles() const +{ + std::vector missingFiles; + for (auto &fileName : required_input_files) + { + if (!fs::is_regular_file(fs::path(base_path.string() + fileName.string()))) + { + missingFiles.push_back(base_path.string() + fileName.string()); + } + } + return missingFiles; +} } // namespace storage } // namespace osrm diff --git a/src/util/coordinate_calculation.cpp b/src/util/coordinate_calculation.cpp index bdc4d1206..ec95a382a 100644 --- a/src/util/coordinate_calculation.cpp +++ b/src/util/coordinate_calculation.cpp @@ -283,7 +283,7 @@ Coordinate interpolateLinear(double factor, const Coordinate from, const Coordin FixedLatitude interpolated_lat{ static_cast(from_lat + factor * (to_lat - from_lat))}; - return {std::move(interpolated_lon), std::move(interpolated_lat)}; + return {interpolated_lon, interpolated_lat}; } // compute the signed area of a triangle diff --git a/test/nodejs/table.js b/test/nodejs/table.js index f4f0e6312..d2c50d83f 100644 --- a/test/nodejs/table.js +++ b/test/nodejs/table.js @@ -130,7 +130,7 @@ tables.forEach(function(annotation) { }); test('table: ' + annotation + ' throws on invalid arguments', function(assert) { - assert.plan(17); + assert.plan(18); var osrm = new OSRM(data_path); var options = {annotations: [annotation.slice(0,-1)]}; assert.throws(function() { osrm.table(options); }, @@ -190,6 +190,8 @@ tables.forEach(function(annotation) { assert.throws(function() { osrm.route({coordinates: two_test_coordinates, generate_hints: null}, function(err, route) {}) }, /generate_hints must be of type Boolean/); + assert.throws(function() { osrm.route({coordinates: two_test_coordinates, skip_waypoints: null}, function(err, route) {}) }, + /skip_waypoints must be of type Boolean/); }); test('table: throws on invalid arguments', function(assert) { @@ -239,6 +241,20 @@ tables.forEach(function(annotation) { }); }); + test('table: ' + annotation + ' table in Monaco without waypoints', function(assert) { + assert.plan(2); + var osrm = new OSRM(data_path); + var options = { + coordinates: two_test_coordinates, + skip_waypoints: true, // false is default + annotations: [annotation.slice(0,-1)] + }; + osrm.table(options, function(err, table) { + assert.strictEqual(table.sources, undefined); + assert.strictEqual(table.destinations, undefined); + }); + }); + test('table: ' + annotation + ' table in Monaco without motorways', function(assert) { assert.plan(2); var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'}); diff --git a/test/nodejs/trip.js b/test/nodejs/trip.js index f26d97b83..683032b3c 100644 --- a/test/nodejs/trip.js +++ b/test/nodejs/trip.js @@ -262,33 +262,19 @@ test('trip: routes Monaco with null hints', function(assert) { }); test('trip: service combinations that are not implemented', function(assert) { - assert.plan(3); + assert.plan(1); var osrm = new OSRM(data_path); - // fixed start, non-roundtrip + // no fixed start, no fixed end, non-roundtrip var options = { coordinates: two_test_coordinates, - source: 'first', + source: 'any', + destination: 'any', roundtrip: false }; osrm.trip(options, function(err, second) { assert.equal('NotImplemented', err.message); }); - - // fixed start, fixed end, non-roundtrip - options.source = 'any'; - options.destination = 'any'; - osrm.trip(options, function(err, second) { - assert.equal('NotImplemented', err.message); - }); - - // fixed end, non-roundtrip - delete options.source; - options.destination = 'last'; - osrm.trip(options, function(err, second) { - assert.equal('NotImplemented', err.message); - }); - }); test('trip: fixed start and end combinations', function(assert) { @@ -302,16 +288,17 @@ test('trip: fixed start and end combinations', function(assert) { geometries: 'geojson' }; - // fixed start and end, non-roundtrip - osrm.trip(options, function(err, fseTrip) { - assert.ifError(err); - assert.equal(1, fseTrip.trips.length); - var coordinates = fseTrip.trips[0].geometry.coordinates; - assert.notEqual(JSON.stringify(coordinates[0]), JSON.stringify(coordinates[coordinates.length - 1])); - }); + // variations of non roundtrip + var nonRoundtripChecks = function(options) { + osrm.trip(options, function(err, fseTrip) { + assert.ifError(err); + assert.equal(1, fseTrip.trips.length); + var coordinates = fseTrip.trips[0].geometry.coordinates; + assert.notEqual(JSON.stringify(coordinates[0]), JSON.stringify(coordinates[coordinates.length - 1])); + }); + }; // variations of roundtrip - var roundtripChecks = function(options) { osrm.trip(options, function(err, trip) { assert.ifError(err); @@ -319,7 +306,20 @@ test('trip: fixed start and end combinations', function(assert) { var coordinates = trip.trips[0].geometry.coordinates; assert.equal(JSON.stringify(coordinates[0]), JSON.stringify(coordinates[coordinates.length - 1])); }); - } + }; + + // fixed start and end, non-roundtrip + nonRoundtripChecks(options); + + // fixed start, non-roundtrip + delete options.destination; + options.source = 'first'; + nonRoundtripChecks(options); + + // fixed end, non-roundtrip + delete options.source; + options.destination = 'last'; + nonRoundtripChecks(options); // roundtrip, source and destination not specified roundtripChecks({coordinates: options.coordinates, geometries: options.geometries}); @@ -327,6 +327,7 @@ test('trip: fixed start and end combinations', function(assert) { // roundtrip, fixed destination options.roundtrip = true; delete options.source; + options.destination = 'last'; roundtripChecks(options); //roundtrip, fixed source diff --git a/unit_tests/contractor/helper.hpp b/unit_tests/contractor/helper.hpp index e0dd159fd..85adfa1fb 100644 --- a/unit_tests/contractor/helper.hpp +++ b/unit_tests/contractor/helper.hpp @@ -36,7 +36,7 @@ inline contractor::ContractorGraph makeGraph(const std::vector &edges) } std::sort(input_edges.begin(), input_edges.end()); - return contractor::ContractorGraph{max_id + 1, std::move(input_edges)}; + return contractor::ContractorGraph{max_id + 1, input_edges}; } } // namespace unit_test } // namespace osrm diff --git a/unit_tests/engine/collapse_internal_route_result.cpp b/unit_tests/engine/collapse_internal_route_result.cpp index fc989ba57..c14fa3967 100644 --- a/unit_tests/engine/collapse_internal_route_result.cpp +++ b/unit_tests/engine/collapse_internal_route_result.cpp @@ -19,8 +19,8 @@ BOOST_AUTO_TEST_CASE(unchanged_collapse_route_result) PhantomNode target; source.forward_segment_id = {1, true}; target.forward_segment_id = {6, true}; - PathData pathy{0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false}; - PathData kathy{0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; + PathData pathy{0, 2, 2, 3, 4, 5, 2, boost::none}; + PathData kathy{0, 1, 1, 2, 3, 4, 1, boost::none}; InternalRouteResult one_leg_result; one_leg_result.unpacked_path_segments = {{pathy, kathy}}; one_leg_result.segment_end_coordinates = {PhantomNodes{source, target}}; @@ -37,13 +37,11 @@ BOOST_AUTO_TEST_CASE(unchanged_collapse_route_result) BOOST_AUTO_TEST_CASE(two_legs_to_one_leg) { - // from_edge_based_node, turn_via_node, name_id, is_segregated, weight_until_turn, - // weight_of_turn, - // duration_until_turn, duration_of_turn, turn_instruction, lane_data, travel_mode, classes, - // entry_class, datasource_id, pre_turn_bearing, post_turn_bearing, left_hand - PathData pathy{0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false}; - PathData kathy{0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; - PathData cathy{0, 3, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; + // from_edge_based_node, turn_via_node, weight_until_turn, weight_of_turn, + // duration_until_turn, duration_of_turn, datasource_id, turn_edge + PathData pathy{0, 2, 2, 3, 4, 5, 2, boost::none}; + PathData kathy{0, 1, 1, 2, 3, 4, 1, boost::none}; + PathData cathy{0, 3, 1, 2, 3, 4, 1, boost::none}; PhantomNode node_1; PhantomNode node_2; PhantomNode node_3; @@ -73,11 +71,11 @@ BOOST_AUTO_TEST_CASE(two_legs_to_one_leg) BOOST_AUTO_TEST_CASE(three_legs_to_two_legs) { - PathData pathy{0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false}; - PathData kathy{0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; - PathData qathy{0, 5, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; - PathData cathy{0, 3, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; - PathData mathy{0, 4, 18, false, 8, 9, 13, 4, 2, {}, 4, 2, {}, 2, {3.0}, {1.0}, false}; + PathData pathy{0, 2, 2, 3, 4, 5, 2, boost::none}; + PathData kathy{0, 1, 1, 2, 3, 4, 1, boost::none}; + PathData qathy{0, 5, 1, 2, 3, 4, 1, boost::none}; + PathData cathy{0, 3, 1, 2, 3, 4, 1, boost::none}; + PathData mathy{0, 4, 8, 9, 13, 4, 2, boost::none}; PhantomNode node_1; PhantomNode node_2; PhantomNode node_3; @@ -117,9 +115,9 @@ BOOST_AUTO_TEST_CASE(three_legs_to_two_legs) BOOST_AUTO_TEST_CASE(two_legs_to_two_legs) { - PathData pathy{0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false}; - PathData kathy{0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; - PathData cathy{0, 3, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; + PathData pathy{0, 2, 2, 3, 4, 5, 2, boost::none}; + PathData kathy{0, 1, 1, 2, 3, 4, 1, boost::none}; + PathData cathy{0, 3, 1, 2, 3, 4, 1, boost::none}; PhantomNode node_1; PhantomNode node_2; PhantomNode node_3; diff --git a/unit_tests/engine/guidance_assembly.cpp b/unit_tests/engine/guidance_assembly.cpp index 2560fb046..10ba1821d 100644 --- a/unit_tests/engine/guidance_assembly.cpp +++ b/unit_tests/engine/guidance_assembly.cpp @@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE(trim_short_segments) {FloatLongitude{-73.981495}, FloatLatitude{40.768275}}}; geometry.segment_offsets = {0, 2}; geometry.segment_distances = {1.9076601161280742}; - geometry.osm_node_ids = {OSMNodeID{0}, OSMNodeID{1}, OSMNodeID{2}}; + geometry.node_ids = {NodeID{0}, NodeID{1}, NodeID{2}}; geometry.annotations = {{1.9076601161280742, 0.2, 0.2, 0}, {0, 0, 0, 0}}; trimShortSegments(steps, geometry); @@ -102,7 +102,7 @@ BOOST_AUTO_TEST_CASE(trim_short_segments) BOOST_CHECK_EQUAL(geometry.segment_offsets.back(), 1); BOOST_CHECK_EQUAL(geometry.annotations.size(), 1); BOOST_CHECK_EQUAL(geometry.locations.size(), 2); - BOOST_CHECK_EQUAL(geometry.osm_node_ids.size(), 2); + BOOST_CHECK_EQUAL(geometry.node_ids.size(), 2); } BOOST_AUTO_TEST_SUITE_END() diff --git a/unit_tests/library/trip.cpp b/unit_tests/library/trip.cpp index 6eb500e81..52308f2e0 100644 --- a/unit_tests/library/trip.cpp +++ b/unit_tests/library/trip.cpp @@ -362,7 +362,7 @@ void test_tfse_illegal_parameters(bool use_json_only_api) ResetParams(locations, params); params.source = TripParameters::SourceType::First; params.roundtrip = false; - CheckNotImplemented(osrm, params, use_json_only_api); + CheckOk(osrm, params, use_json_only_api); ResetParams(locations, params); params.destination = TripParameters::DestinationType::Any; @@ -372,7 +372,7 @@ void test_tfse_illegal_parameters(bool use_json_only_api) ResetParams(locations, params); params.destination = TripParameters::DestinationType::Last; params.roundtrip = false; - CheckNotImplemented(osrm, params, use_json_only_api); + CheckOk(osrm, params, use_json_only_api); // three parameters set params.source = TripParameters::SourceType::Any; @@ -383,12 +383,12 @@ void test_tfse_illegal_parameters(bool use_json_only_api) params.source = TripParameters::SourceType::Any; params.destination = TripParameters::DestinationType::Last; params.roundtrip = false; - CheckNotImplemented(osrm, params, use_json_only_api); + CheckOk(osrm, params, use_json_only_api); params.source = TripParameters::SourceType::First; params.destination = TripParameters::DestinationType::Any; params.roundtrip = false; - CheckNotImplemented(osrm, params, use_json_only_api); + CheckOk(osrm, params, use_json_only_api); } BOOST_AUTO_TEST_CASE(test_tfse_illegal_parameters_old_api) { test_tfse_illegal_parameters(true); } BOOST_AUTO_TEST_CASE(test_tfse_illegal_parameters_new_api) { test_tfse_illegal_parameters(false); }