Merge branch 'master' into sf-tbb3
This commit is contained in:
commit
d68f66f759
@ -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,
|
||||
|
||||
14
.github/workflows/osrm-backend.yml
vendored
14
.github/workflows/osrm-backend.yml
vendored
@ -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"
|
||||
|
||||
11
CHANGELOG.md
11
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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 |
|
||||
|
||||
@ -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 |
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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 |
|
||||
| 3 | 1400.1 | 400 | 0 |
|
||||
|
||||
|
||||
@ -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 |
|
||||
| 4321 | 1.00027,1,1.000135,1 | 15.02597 | 1.5 | 1.5 | 1.5 |
|
||||
|
||||
|
||||
@ -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 |
|
||||
| x | p | xh,xh |
|
||||
|
||||
@ -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 |
|
||||
| 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 |
|
||||
|
||||
@ -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 |
|
||||
|
||||
@ -23,7 +23,7 @@ inline auto contractFullGraph(ContractorGraph contractor_graph,
|
||||
auto edges = toEdges<QueryEdge>(std::move(contractor_graph));
|
||||
std::vector<bool> 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<QueryEdge>(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
|
||||
|
||||
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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<uint32_t> 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<uint64_t>(node_id));
|
||||
nodes.emplace_back(static_cast<uint64_t>(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<std::uint64_t>(node_id));
|
||||
nodes.values.push_back(
|
||||
static_cast<std::uint64_t>(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));
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -36,24 +36,27 @@ template <> class AlgorithmDataFacade<CH>
|
||||
|
||||
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<bool(EdgeData)> filter) const = 0;
|
||||
};
|
||||
|
||||
@ -70,23 +73,24 @@ template <> class AlgorithmDataFacade<MLD>
|
||||
|
||||
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<MLD>
|
||||
|
||||
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
|
||||
|
||||
@ -73,45 +73,52 @@ class ContiguousInternalMemoryAlgorithmDataFacade<CH> : 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<bool(EdgeData)> 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<RTreeLeaf, storage::Ownership::View>;
|
||||
using SharedGeospatialQuery = GeospatialQuery<SharedRTree, BaseDataFacade>;
|
||||
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<RTreeLeaf> 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<std::string> 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<extractor::ManeuverOverride>
|
||||
@ -691,57 +705,62 @@ template <> class ContiguousInternalMemoryAlgorithmDataFacade<MLD> : 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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -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<std::string> 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<extractor::ManeuverOverride>
|
||||
GetOverridesThatStartAt(const NodeID edge_based_node_id) const = 0;
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -75,10 +75,14 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
|
||||
|
||||
std::vector<NamedSegment> 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<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
inline std::string assembleSummary(const datafacade::BaseDataFacade &facade,
|
||||
const std::vector<PathData> &route_data,
|
||||
const PhantomNode &target_node,
|
||||
const bool target_traversed_in_reverse)
|
||||
{
|
||||
auto summary_array = detail::summarizeRoute<detail::MAX_USED_SEGMENTS>(
|
||||
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<PathData> &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<detail::MAX_USED_SEGMENTS>(
|
||||
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,
|
||||
"",
|
||||
{}};
|
||||
}
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <cstddef>
|
||||
#include <guidance/turn_bearing.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
@ -96,7 +97,7 @@ inline std::vector<RouteStep> 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<RouteStep> 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<RouteStep> 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<RouteStep> 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<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
|
||||
}
|
||||
|
||||
// extract bearings
|
||||
bearings = std::make_pair<std::uint16_t, std::uint16_t>(
|
||||
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<std::uint16_t, std::uint16_t>(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<RouteStep> 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<std::size_t>(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<RouteStep> 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<RouteStep> 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},
|
||||
|
||||
@ -32,7 +32,7 @@ struct LegGeometry
|
||||
// length of the segment in meters
|
||||
std::vector<double> segment_distances;
|
||||
// original OSM node IDs for each coordinate
|
||||
std::vector<OSMNodeID> osm_node_ids;
|
||||
std::vector<NodeID> node_ids;
|
||||
|
||||
// Per-coordinate metadata
|
||||
struct Annotation
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <vector>
|
||||
|
||||
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<EdgeID> turn_edge;
|
||||
};
|
||||
|
||||
struct InternalRouteResult
|
||||
|
||||
@ -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<EdgeWeight>(weight_vector[segment_idx]),
|
||||
0,
|
||||
static_cast<EdgeDuration>(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<std::size_t>(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<EdgeWeight>(weight_vector[segment_idx]),
|
||||
0,
|
||||
static_cast<EdgeDuration>(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
|
||||
|
||||
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ class RestrictionParser
|
||||
RestrictionParser(bool use_turn_restrictions,
|
||||
bool parse_conditionals,
|
||||
std::vector<std::string> &restrictions);
|
||||
boost::optional<InputTurnRestriction> TryParse(const osmium::Relation &relation) const;
|
||||
std::vector<InputTurnRestriction> TryParse(const osmium::Relation &relation) const;
|
||||
|
||||
private:
|
||||
bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;
|
||||
|
||||
@ -675,6 +675,22 @@ inline bool argumentsToParameter(const Nan::FunctionCallbackInfo<v8::Value> &arg
|
||||
params->generate_hints = Nan::To<bool>(generate_hints).FromJust();
|
||||
}
|
||||
|
||||
if (Nan::Has(obj, Nan::New("skip_waypoints").ToLocalChecked()).FromJust())
|
||||
{
|
||||
v8::Local<v8::Value> 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<bool>(skip_waypoints).FromJust();
|
||||
}
|
||||
|
||||
if (Nan::Has(obj, Nan::New("exclude").ToLocalChecked()).FromJust())
|
||||
{
|
||||
v8::Local<v8::Value> exclude =
|
||||
|
||||
@ -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_)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -195,7 +195,7 @@ inline DynamicEdgeBasedGraph LoadEdgeBasedGraph(const boost::filesystem::path &p
|
||||
auto directed = splitBidirectionalEdges(edges);
|
||||
auto tidied = prepareEdgesForUsageInGraph<DynamicEdgeBasedGraphEdge>(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
|
||||
|
||||
@ -25,6 +25,7 @@ struct IOConfig
|
||||
}
|
||||
|
||||
bool IsValid() const;
|
||||
std::vector<std::string> GetMissingFiles() const;
|
||||
boost::filesystem::path GetPath(const std::string &fileName) const
|
||||
{
|
||||
if (!IsConfigured(fileName, required_input_files) &&
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -77,7 +77,7 @@ inline auto make_name_table_view(const SharedDataIndex &index, const std::string
|
||||
auto values =
|
||||
make_vector_view<extractor::NameTableView::IndexedData::ValueType>(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<DatasourceID>(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<RTreeLeaf, storage::Ownership::View>{
|
||||
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<DiscreteBearing>(index, name + "/bearing_values");
|
||||
util::RangeTable<16, storage::Ownership::View> bearing_range_table(
|
||||
std::move(bearing_offsets),
|
||||
std::move(bearing_blocks),
|
||||
static_cast<unsigned>(bearing_values.size()));
|
||||
bearing_offsets, bearing_blocks, static_cast<unsigned>(bearing_values.size()));
|
||||
|
||||
auto bearing_class_id = make_vector_view<BearingClassID>(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<bool>(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<PartitionID>(index, name + "/partition");
|
||||
auto cell_to_children = make_vector_view<CellID>(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<partitioner::CellStorageView::CellData>(index, name + "/cells");
|
||||
auto level_offsets = make_vector_view<std::uint64_t>(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<EdgeDuration>(index, durations_block_id);
|
||||
auto distances = make_vector_view<EdgeDistance>(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<EdgeDuration>(index, durations_block_id);
|
||||
auto distances = make_vector_view<EdgeDistance>(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<bool>(index, name + "/is_forward_edge");
|
||||
auto is_backward_edge = make_vector_view<bool>(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)
|
||||
|
||||
@ -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<std::size_t>::max();
|
||||
|
||||
@ -95,16 +95,13 @@ static const LaneDescriptionID INVALID_LANE_DESCRIPTIONID =
|
||||
std::numeric_limits<LaneDescriptionID>::max();
|
||||
|
||||
using BearingClassID = std::uint32_t;
|
||||
static const BearingClassID INVALID_BEARING_CLASSID = std::numeric_limits<BearingClassID>::max();
|
||||
|
||||
using DiscreteBearing = std::uint16_t;
|
||||
|
||||
using EntryClassID = std::uint16_t;
|
||||
static const EntryClassID INVALID_ENTRY_CLASSID = std::numeric_limits<EntryClassID>::max();
|
||||
|
||||
static const NodeID SPECIAL_NODEID = std::numeric_limits<NodeID>::max();
|
||||
static const NodeID SPECIAL_SEGMENTID = std::numeric_limits<NodeID>::max() >> 1;
|
||||
static const NodeID SPECIAL_GEOMETRYID = std::numeric_limits<NodeID>::max() >> 1;
|
||||
static const PackedGeometryID SPECIAL_GEOMETRYID =
|
||||
std::numeric_limits<PackedGeometryID>::max() >> 1;
|
||||
static const EdgeID SPECIAL_EDGEID = std::numeric_limits<EdgeID>::max();
|
||||
static const RestrictionID SPECIAL_RESTRICTIONID = std::numeric_limits<RestrictionID>::max();
|
||||
static const NameID INVALID_NAMEID = std::numeric_limits<NameID>::max();
|
||||
@ -123,13 +120,6 @@ static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>
|
||||
static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
|
||||
static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits<double>::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<unsigned>::max() >> 1), forward(false) {}
|
||||
|
||||
NodeID id : 31;
|
||||
PackedGeometryID id : 31;
|
||||
std::uint32_t forward : 1;
|
||||
};
|
||||
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -279,8 +279,7 @@ void trimShortSegments(std::vector<RouteStep> &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<RouteStep> &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<RouteStep> &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<RouteStep> &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<RouteStep> buildIntersections(std::vector<RouteStep> 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.
|
||||
|
||||
@ -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<EdgeWeight> &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<size_t>(0, result_table.GetNumberOfNodes()))
|
||||
{
|
||||
result_table.SetValue(i, source_id, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ManipulateTableForNonRoundtripFE(const std::size_t destination_id,
|
||||
util::DistTableWrapper<EdgeWeight> &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<size_t>(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<NodeID> 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
|
||||
|
||||
@ -851,7 +851,7 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &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<WeightedViaNodePackedPath> weighted_packed_paths;
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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++;
|
||||
|
||||
@ -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, {}));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -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<InputTurnRestriction>
|
||||
std::vector<InputTurnRestriction>
|
||||
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<std::uint64_t>::max();
|
||||
auto from = INVALID_OSM_ID;
|
||||
std::vector<OSMWayID> from_ways;
|
||||
auto via_node = INVALID_OSM_ID;
|
||||
std::vector<OSMWayID> via_ways;
|
||||
auto to = INVALID_OSM_ID;
|
||||
std::vector<OSMWayID> 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<std::uint64_t>(member.ref());
|
||||
from_ways.push_back({static_cast<std::uint64_t>(member.ref())});
|
||||
}
|
||||
else if (0 == strcmp("to", role))
|
||||
{
|
||||
to = static_cast<std::uint64_t>(member.ref());
|
||||
to_ways.push_back({static_cast<std::uint64_t>(member.ref())});
|
||||
}
|
||||
else if (0 == strcmp("via", role))
|
||||
{
|
||||
@ -178,6 +185,7 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<util::OpeningHours> condition;
|
||||
// parse conditional tags
|
||||
if (parse_conditionals)
|
||||
{
|
||||
@ -199,32 +207,54 @@ RestrictionParser::TryParse(const osmium::Relation &relation) const
|
||||
std::vector<util::OpeningHours> 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<InputTurnRestriction> 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
|
||||
|
||||
@ -909,13 +909,15 @@ void Sol2ScriptingEnvironment::ProcessElements(
|
||||
case osmium::item_type::relation:
|
||||
{
|
||||
const auto &relation = static_cast<const osmium::Relation &>(*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;
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
#include "engine/engine_config.hpp"
|
||||
#include "engine/status.hpp"
|
||||
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
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
|
||||
|
||||
@ -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_}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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<std::string> IOConfig::GetMissingFiles() const
|
||||
{
|
||||
std::vector<std::string> 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
|
||||
|
||||
@ -283,7 +283,7 @@ Coordinate interpolateLinear(double factor, const Coordinate from, const Coordin
|
||||
FixedLatitude interpolated_lat{
|
||||
static_cast<std::int32_t>(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
|
||||
|
||||
@ -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'});
|
||||
|
||||
@ -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
|
||||
|
||||
@ -36,7 +36,7 @@ inline contractor::ContractorGraph makeGraph(const std::vector<TestEdge> &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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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); }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user