Compare commits
123 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cf5e0dc907 | |||
| 065c1abad0 | |||
| 1a7ea8cb87 | |||
| ef3ece9865 | |||
| 23a7f9e9a0 | |||
| 6742100c36 | |||
| e36dc52da3 | |||
| afcb84282d | |||
| f25d56a7ec | |||
| c428e8a8a0 | |||
| c00fc59c6b | |||
| 2d76363237 | |||
| 40039cd752 | |||
| b42a7326be | |||
| cf34a3e0bd | |||
| 3381aa8e21 | |||
| 3d5a279aea | |||
| ccc5465286 | |||
| 4dd7846971 | |||
| 4da5804939 | |||
| 47edf679b5 | |||
| b82f87df1f | |||
| e217951aec | |||
| f8e37907cb | |||
| 5a48ce85b3 | |||
| 7d72dfebf7 | |||
| 3d01d96036 | |||
| e8da3d9231 | |||
| d9ce9cf780 | |||
| 3285ce3b2f | |||
| f1eabc3ecc | |||
| c3f2a6cdb9 | |||
| 97f676d5a3 | |||
| 7ffc08be28 | |||
| feb9389436 | |||
| a0eda3e7d7 | |||
| 7652f6ca6b | |||
| aa4e6b1cf3 | |||
| de2f392960 | |||
| 0188d2bccd | |||
| 054161fc7e | |||
| 89435aa87f | |||
| 0cbb23abe1 | |||
| a2915f78c5 | |||
| 99cb17aed3 | |||
| 8fd8d0c24a | |||
| c57b0d28b0 | |||
| 523ee762f0 | |||
| feeed75cf1 | |||
| c7ee1a59eb | |||
| 2725202771 | |||
| 42fafdcdfe | |||
| c8de759cd6 | |||
| fb9d1cefcc | |||
| a9b1bd88d3 | |||
| 1ff096ac5c | |||
| 0ea757ed02 | |||
| 42cbca0ff0 | |||
| c1ed73126d | |||
| 01b1673c8a | |||
| d4dc297f75 | |||
| 9aaab7a53f | |||
| 1a6f4c44e7 | |||
| 163a2cfe3c | |||
| 667fd198ac | |||
| b7a990d0b5 | |||
| 8306ed8ae3 | |||
| 640df69aa1 | |||
| 8b48e2ccc6 | |||
| babdced52f | |||
| 21607e0cb2 | |||
| 24646aada9 | |||
| 51b74a99aa | |||
| ed5003b502 | |||
| 46dc660801 | |||
| 73fb53cf36 | |||
| efe6840d08 | |||
| d259848456 | |||
| 8a82d3929c | |||
| 89fce286a7 | |||
| 11c7ddc84d | |||
| 54e50a67a8 | |||
| c00c157479 | |||
| ee8e0f890a | |||
| 1e2ffee97c | |||
| ffc39b8ad2 | |||
| 70969186f6 | |||
| dff76d31d5 | |||
| 3254686933 | |||
| a6dfff725b | |||
| 10237b8761 | |||
| 79de092bb2 | |||
| 82aa369db3 | |||
| 0583582772 | |||
| 99809e105c | |||
| 6d361ced41 | |||
| 790fa901c7 | |||
| 7f9d591ab7 | |||
| b503e96a98 | |||
| d691af4860 | |||
| befd9dc5ae | |||
| 4968d7f9d9 | |||
| c26f0612d1 | |||
| de41299eda | |||
| c37bbfd07a | |||
| 0fd1fb2904 | |||
| 7ebd21f39e | |||
| 8ef366e061 | |||
| 367933fc1a | |||
| c28ba66039 | |||
| d0e3e2af23 | |||
| 8526cc7d45 | |||
| 016440fc7e | |||
| 6e77d53946 | |||
| 99875b4d24 | |||
| c315a586f7 | |||
| 69c38401bc | |||
| e219eb9442 | |||
| 31e31a63d0 | |||
| b437ce5b33 | |||
| 5723eaaa6a | |||
| 0f7b86b099 | |||
| 14dcf91812 |
+11
-1
@@ -13,6 +13,10 @@ Checks: >
|
|||||||
-bugprone-forward-declaration-namespace,
|
-bugprone-forward-declaration-namespace,
|
||||||
-bugprone-sizeof-expression,
|
-bugprone-sizeof-expression,
|
||||||
-bugprone-throw-keyword-missing,
|
-bugprone-throw-keyword-missing,
|
||||||
|
-bugprone-chained-comparison,
|
||||||
|
-bugprone-incorrect-enable-if,
|
||||||
|
-bugprone-switch-missing-default-case,
|
||||||
|
-bugprone-empty-catch,
|
||||||
-clang-analyzer-*,
|
-clang-analyzer-*,
|
||||||
-clang-diagnostic-deprecated-declarations,
|
-clang-diagnostic-deprecated-declarations,
|
||||||
-clang-diagnostic-constant-conversion,
|
-clang-diagnostic-constant-conversion,
|
||||||
@@ -49,11 +53,13 @@ Checks: >
|
|||||||
-misc-misplaced-const,
|
-misc-misplaced-const,
|
||||||
-misc-definitions-in-headers,
|
-misc-definitions-in-headers,
|
||||||
-misc-unused-parameters,
|
-misc-unused-parameters,
|
||||||
|
-misc-include-cleaner,
|
||||||
modernize-concat-nested-namespaces,
|
modernize-concat-nested-namespaces,
|
||||||
modernize-use-using,
|
modernize-use-using,
|
||||||
performance-*,
|
performance-*,
|
||||||
-performance-noexcept-move-constructor,
|
|
||||||
-performance-no-int-to-ptr,
|
-performance-no-int-to-ptr,
|
||||||
|
-performance-enum-size,
|
||||||
|
-performance-avoid-endl,
|
||||||
readability-*,
|
readability-*,
|
||||||
-readability-avoid-const-params-in-decls,
|
-readability-avoid-const-params-in-decls,
|
||||||
-readability-braces-around-statements,
|
-readability-braces-around-statements,
|
||||||
@@ -82,6 +88,10 @@ Checks: >
|
|||||||
-readability-make-member-function-const,
|
-readability-make-member-function-const,
|
||||||
-readability-redundant-string-init,
|
-readability-redundant-string-init,
|
||||||
-readability-non-const-parameter,
|
-readability-non-const-parameter,
|
||||||
|
-readability-redundant-inline-specifier,
|
||||||
|
-readability-avoid-nested-conditional-operator,
|
||||||
|
-readability-avoid-return-with-void-value,
|
||||||
|
-readability-redundant-casting,
|
||||||
-readability-static-accessed-through-instance
|
-readability-static-accessed-through-instance
|
||||||
|
|
||||||
WarningsAsErrors: '*'
|
WarningsAsErrors: '*'
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
name: Question
|
|
||||||
about: Ask a question about OSRM
|
|
||||||
labels: question
|
|
||||||
---
|
|
||||||
@@ -6,6 +6,9 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish:
|
publish:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
docker-base-image: ["debian", "alpine"]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check out the repo
|
- name: Check out the repo
|
||||||
@@ -53,10 +56,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
push: true
|
push: true
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
file: ./docker/Dockerfile
|
file: ./docker/Dockerfile-${{ matrix.docker-base-image }}
|
||||||
tags: ${{ steps.metadebug.outputs.tags }}
|
tags: ${{ steps.metadebug.outputs.tags }}
|
||||||
build-args: |
|
build-args: |
|
||||||
DOCKER_TAG=${{ join(steps.metadebug.outputs.tags ) }}
|
DOCKER_TAG=${{ join(steps.metadebug.outputs.tags ) }}-${{ matrix.docker-base-image }}
|
||||||
|
|
||||||
|
|
||||||
- name: Build container image - assertions
|
- name: Build container image - assertions
|
||||||
@@ -64,10 +67,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
push: true
|
push: true
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
file: ./docker/Dockerfile
|
file: ./docker/Dockerfile-${{ matrix.docker-base-image }}
|
||||||
tags: ${{ steps.metaassertions.outputs.tags }}
|
tags: ${{ steps.metaassertions.outputs.tags }}
|
||||||
build-args: |
|
build-args: |
|
||||||
DOCKER_TAG=${{ join(steps.metaassertions.outputs.tags ) }}
|
DOCKER_TAG=${{ join(steps.metaassertions.outputs.tags ) }}-${{ matrix.docker-base-image }}
|
||||||
|
|
||||||
# build and publish "normal" image as last to get it listed on top
|
# build and publish "normal" image as last to get it listed on top
|
||||||
- name: Build container image - normal
|
- name: Build container image - normal
|
||||||
@@ -75,10 +78,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
push: true
|
push: true
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
file: ./docker/Dockerfile
|
file: ./docker/Dockerfile-${{ matrix.docker-base-image }}
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
build-args: |
|
build-args: |
|
||||||
DOCKER_TAG=${{ join(steps.meta.outputs.tags ) }}
|
DOCKER_TAG=${{ join(steps.meta.outputs.tags ) }}-${{ matrix.docker-base-image }}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+746
-623
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,24 @@
|
|||||||
|
name: 'Close stale issues'
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '30 1 * * *' # every day at 1:30am
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v9
|
||||||
|
with:
|
||||||
|
stale-issue-message: 'This issue seems to be stale. It will be closed in 30 days if no further activity occurs.'
|
||||||
|
stale-pr-message: 'This PR seems to be stale. Is it still relevant?'
|
||||||
|
days-before-issue-stale: 180 # 6 months
|
||||||
|
days-before-issue-close: 30 # 1 month
|
||||||
|
days-before-pr-stale: 180 # 6 months
|
||||||
|
days-before-pr-close: -1 # never close PRs
|
||||||
|
exempt-issue-labels: 'Do Not Stale,Feature Request,Performance,Bug Report,CI,Starter Task,Refactor,Guidance'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,17 +1,54 @@
|
|||||||
# Unreleased
|
# Unreleased
|
||||||
- Changes from 5.27.1
|
- Changes from 5.27.1
|
||||||
- Features
|
- Features
|
||||||
|
- REMOVED: Remove all core-CH left-overs [#6920](https://github.com/Project-OSRM/osrm-backend/pull/6920)
|
||||||
|
- ADDED: Add support for a keepalive_timeout flag. [#6674](https://github.com/Project-OSRM/osrm-backend/pull/6674)
|
||||||
- ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575)
|
- ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575)
|
||||||
- ADDED: Add support for disabling feature datasets. [#6666](https://github.com/Project-OSRM/osrm-backend/pull/6666)
|
- ADDED: Add support for disabling feature datasets. [#6666](https://github.com/Project-OSRM/osrm-backend/pull/6666)
|
||||||
|
- ADDED: Add support for opposite approach request parameter. [#6842](https://github.com/Project-OSRM/osrm-backend/pull/6842)
|
||||||
|
- ADDED: Add support for accessing edge flags in `process_segment` [#6658](https://github.com/Project-OSRM/osrm-backend/pull/6658)
|
||||||
- Build:
|
- Build:
|
||||||
|
- CHANGED: Upgrade clang-format to version 15. [#6919](https://github.com/Project-OSRM/osrm-backend/pull/6919)
|
||||||
|
- CHANGED: Use Debian Bookworm as base Docker image [#6904](https://github.com/Project-OSRM/osrm-backend/pull/6904)
|
||||||
|
- CHANGED: Upgrade CI actions to latest versions [#6893](https://github.com/Project-OSRM/osrm-backend/pull/6893)
|
||||||
|
- CHANGED: Remove outdated warnings #6894 [#6894](https://github.com/Project-OSRM/osrm-backend/pull/6894)
|
||||||
- ADDED: Add CI job which builds OSRM with gcc 12. [#6455](https://github.com/Project-OSRM/osrm-backend/pull/6455)
|
- ADDED: Add CI job which builds OSRM with gcc 12. [#6455](https://github.com/Project-OSRM/osrm-backend/pull/6455)
|
||||||
- CHANGED: Upgrade to clang-tidy 15. [#6439](https://github.com/Project-OSRM/osrm-backend/pull/6439)
|
- CHANGED: Upgrade to clang-tidy 15. [#6439](https://github.com/Project-OSRM/osrm-backend/pull/6439)
|
||||||
- CHANGED: Update actions/cache to v3. [#6420](https://github.com/Project-OSRM/osrm-backend/pull/6420)
|
- CHANGED: Update actions/cache to v3. [#6420](https://github.com/Project-OSRM/osrm-backend/pull/6420)
|
||||||
- REMOVED: Drop support of Node 12 & 14. [#6431](https://github.com/Project-OSRM/osrm-backend/pull/6431)
|
- REMOVED: Drop support of Node 12 & 14. [#6431](https://github.com/Project-OSRM/osrm-backend/pull/6431)
|
||||||
- ADDED: Add 'load directly' mode to default Cucumber test suite. [#6663](https://github.com/Project-OSRM/osrm-backend/pull/6663)
|
- ADDED: Add 'load directly' mode to default Cucumber test suite. [#6663](https://github.com/Project-OSRM/osrm-backend/pull/6663)
|
||||||
|
- CHANGED: Fix compilation for Boost 1.85.0 [#6856](https://github.com/Project-OSRM/osrm-backend/pull/6856)
|
||||||
|
- CHANGED: Drop support for Node 16 [#6855](https://github.com/Project-OSRM/osrm-backend/pull/6855)
|
||||||
|
- REMOVED: Remove unused AppVeyor files [#6860](https://github.com/Project-OSRM/osrm-backend/pull/6860)
|
||||||
|
- CHANGED: Upgrade clang-format to version 15 [#6859](https://github.com/Project-OSRM/osrm-backend/pull/6859)
|
||||||
- NodeJS:
|
- NodeJS:
|
||||||
- CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452)
|
- CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452)
|
||||||
- Misc:
|
- Misc:
|
||||||
|
- CHANGED: Optimise encodePolyline function. [#6940](https://github.com/Project-OSRM/osrm-backend/pull/6940)
|
||||||
|
- CHANGED: Avoid reallocations in base64 encoding. [#6951](https://github.com/Project-OSRM/osrm-backend/pull/6951)
|
||||||
|
- CHANGED: Get rid of unused Boost dependencies. [#6960](https://github.com/Project-OSRM/osrm-backend/pull/6960)
|
||||||
|
- CHANGED: Apply micro-optimisation for Table & Trip APIs. [#6949](https://github.com/Project-OSRM/osrm-backend/pull/6949)
|
||||||
|
- CHANGED: Apply micro-optimisation for Route API. [#6948](https://github.com/Project-OSRM/osrm-backend/pull/6948)
|
||||||
|
- CHANGED: Apply micro-optimisation for Match API. [#6945](https://github.com/Project-OSRM/osrm-backend/pull/6945)
|
||||||
|
- CHANGED: Apply micro-optimisation for Nearest API. [#6944](https://github.com/Project-OSRM/osrm-backend/pull/6944)
|
||||||
|
- CHANGED: Avoid copy of intersection in totalTurnAngle. [#6938](https://github.com/Project-OSRM/osrm-backend/pull/6938)
|
||||||
|
- CHANGED: Use std::unordered_map::emplace instead of operator[] when producing JSONs. [#6936](https://github.com/Project-OSRM/osrm-backend/pull/6936)
|
||||||
|
- CHANGED: Avoid copy of vectors in MakeRoute function. [#6939](https://github.com/Project-OSRM/osrm-backend/pull/6939)
|
||||||
|
- FIXED: Fix bugprone-unused-return-value clang-tidy warning. [#6934](https://github.com/Project-OSRM/osrm-backend/pull/6934)
|
||||||
|
- FIXED: Fix performance-noexcept-move-constructor clang-tidy warning. [#6931](https://github.com/Project-OSRM/osrm-backend/pull/6933)
|
||||||
|
- FIXED: Fix performance-noexcept-swap clang-tidy warning. [#6931](https://github.com/Project-OSRM/osrm-backend/pull/6931)
|
||||||
|
- CHANGED: Use custom struct instead of std::pair in QueryHeap. [#6921](https://github.com/Project-OSRM/osrm-backend/pull/6921)
|
||||||
|
- CHANGED: Use std::string_view::starts_with instead of boost::starts_with. [#6918](https://github.com/Project-OSRM/osrm-backend/pull/6918)
|
||||||
|
- CHANGED: Get rid of boost::math::constants::* and M_PI in favor of std::numbers. [#6916](https://github.com/Project-OSRM/osrm-backend/pull/6916)
|
||||||
|
- CHANGED: Make constants in PackedVector constexpr. [#6917](https://github.com/Project-OSRM/osrm-backend/pull/6917)
|
||||||
|
- CHANGED: Use std::variant instead of mapbox::util::variant. [#6903](https://github.com/Project-OSRM/osrm-backend/pull/6903)
|
||||||
|
- CHANGED: Bump rapidjson to version f9d53419e912910fd8fa57d5705fa41425428c35 [#6906](https://github.com/Project-OSRM/osrm-backend/pull/6906)
|
||||||
|
- CHANGED: Bump mapbox/variant to version 1.2.0 [#6898](https://github.com/Project-OSRM/osrm-backend/pull/6898)
|
||||||
|
- CHANGED: Avoid copy of std::function-based callback in path unpacking [#6895](https://github.com/Project-OSRM/osrm-backend/pull/6895)
|
||||||
|
- CHANGED: Replace boost::hash by std::hash [#6892](https://github.com/Project-OSRM/osrm-backend/pull/6892)
|
||||||
|
- CHANGED: Partial fix migration from boost::optional to std::optional [#6551](https://github.com/Project-OSRM/osrm-backend/issues/6551)
|
||||||
|
- CHANGED: Replace boost::filesystem with std::filesystem [#6432](https://github.com/Project-OSRM/osrm-backend/pull/6432)
|
||||||
|
- CHANGED: Update Conan Boost version to 1.85.0. [#6868](https://github.com/Project-OSRM/osrm-backend/pull/6868)
|
||||||
- FIXED: Fix an error in a RouteParameters AnnotationsType operator overload. [#6646](https://github.com/Project-OSRM/osrm-backend/pull/6646)
|
- FIXED: Fix an error in a RouteParameters AnnotationsType operator overload. [#6646](https://github.com/Project-OSRM/osrm-backend/pull/6646)
|
||||||
- ADDED: Add support for "unlimited" to be passed as a value for the default-radius and max-matching-radius flags. [#6599](https://github.com/Project-OSRM/osrm-backend/pull/6599)
|
- ADDED: Add support for "unlimited" to be passed as a value for the default-radius and max-matching-radius flags. [#6599](https://github.com/Project-OSRM/osrm-backend/pull/6599)
|
||||||
- CHANGED: Allow -1.0 as unlimited for default_radius value. [#6599](https://github.com/Project-OSRM/osrm-backend/pull/6599)
|
- CHANGED: Allow -1.0 as unlimited for default_radius value. [#6599](https://github.com/Project-OSRM/osrm-backend/pull/6599)
|
||||||
@@ -30,10 +67,22 @@
|
|||||||
- FIXED: Added a variable to preprocessor guard in file osrm-backend/include/util/range_table.hpp to solve build error. [#6596](https://github.com/Project-OSRM/osrm-backend/pull/6596)
|
- FIXED: Added a variable to preprocessor guard in file osrm-backend/include/util/range_table.hpp to solve build error. [#6596](https://github.com/Project-OSRM/osrm-backend/pull/6596)
|
||||||
- FIXED: Ensure required file check in osrm-routed is correctly enforced. [#6655](https://github.com/Project-OSRM/osrm-backend/pull/6655)
|
- FIXED: Ensure required file check in osrm-routed is correctly enforced. [#6655](https://github.com/Project-OSRM/osrm-backend/pull/6655)
|
||||||
- FIXED: Correct HTTP docs to reflect summary output dependency on steps parameter. [#6655](https://github.com/Project-OSRM/osrm-backend/pull/6655)
|
- FIXED: Correct HTTP docs to reflect summary output dependency on steps parameter. [#6655](https://github.com/Project-OSRM/osrm-backend/pull/6655)
|
||||||
|
- ADDED: Extract prerelease/build information from package semver [#6839](https://github.com/Project-OSRM/osrm-backend/pull/6839)
|
||||||
- Profiles:
|
- Profiles:
|
||||||
- FIXED: Bicycle and foot profiles now don't route on proposed ways [#6615](https://github.com/Project-OSRM/osrm-backend/pull/6615)
|
- FIXED: Bicycle and foot profiles now don't route on proposed ways [#6615](https://github.com/Project-OSRM/osrm-backend/pull/6615)
|
||||||
- Routing:
|
- Routing:
|
||||||
- FIXED: Fix adding traffic signal penalties during compression [#6419](https://github.com/Project-OSRM/osrm-backend/pull/6419)
|
- FIXED: Fix adding traffic signal penalties during compression [#6419](https://github.com/Project-OSRM/osrm-backend/pull/6419)
|
||||||
|
- FIXED: Correctly handle compressed traffic signals. [#6724](https://github.com/Project-OSRM/osrm-backend/pull/6724)
|
||||||
|
- FIXED: Fix bug when searching for maneuver overrides [#6739](https://github.com/Project-OSRM/osrm-backend/pull/6739)
|
||||||
|
- FIXED: Remove force-loop checks for routes with u-turns [#6858](https://github.com/Project-OSRM/osrm-backend/pull/6858)
|
||||||
|
- FIXED: Correctly check runtime search conditions for forcing routing steps [#6866](https://github.com/Project-OSRM/osrm-backend/pull/6866)
|
||||||
|
- Map Matching:
|
||||||
|
- CHANGED: Optimise path distance calculation in MLD map matching even more. [#6884](https://github.com/Project-OSRM/osrm-backend/pull/6884)
|
||||||
|
- CHANGED: Optimise path distance calculation in MLD map matching. [#6876](https://github.com/Project-OSRM/osrm-backend/pull/6876)
|
||||||
|
- CHANGED: Optimise R-tree queries in the case of map matching. [#6881](https://github.com/Project-OSRM/osrm-backend/pull/6876)
|
||||||
|
- Debug tiles:
|
||||||
|
- FIXED: Ensure speed layer features have unique ids. [#6726](https://github.com/Project-OSRM/osrm-backend/pull/6726)
|
||||||
|
|
||||||
# 5.27.1
|
# 5.27.1
|
||||||
- Changes from 5.27.0
|
- Changes from 5.27.0
|
||||||
- Misc:
|
- Misc:
|
||||||
|
|||||||
+62
-69
@@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.18)
|
cmake_minimum_required(VERSION 3.18)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
@@ -42,16 +42,13 @@ if (ENABLE_CLANG_TIDY)
|
|||||||
message(FATAL_ERROR "ENABLE_CLANG_TIDY is ON but clang-tidy is not found!")
|
message(FATAL_ERROR "ENABLE_CLANG_TIDY is ON but clang-tidy is not found!")
|
||||||
else()
|
else()
|
||||||
message(STATUS "Found clang-tidy at ${CLANG_TIDY_COMMAND}")
|
message(STATUS "Found clang-tidy at ${CLANG_TIDY_COMMAND}")
|
||||||
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND};--warnings-as-errors=*")
|
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND};--warnings-as-errors=*;--header-filter=.*")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
# be compatible with version handling before cmake 3.x
|
# be compatible with version handling before cmake 3.x
|
||||||
if (POLICY CMP0048)
|
|
||||||
cmake_policy(SET CMP0048 OLD)
|
|
||||||
endif()
|
|
||||||
if (POLICY CMP0057)
|
if (POLICY CMP0057)
|
||||||
cmake_policy(SET CMP0057 NEW)
|
cmake_policy(SET CMP0057 NEW)
|
||||||
endif()
|
endif()
|
||||||
@@ -73,14 +70,17 @@ include(JSONParser)
|
|||||||
file(READ "package.json" packagejsonraw)
|
file(READ "package.json" packagejsonraw)
|
||||||
sbeParseJson(packagejson packagejsonraw)
|
sbeParseJson(packagejson packagejsonraw)
|
||||||
|
|
||||||
if (packagejson.version MATCHES "^([0-9]+)\.([0-9]+)\.([0-9]+)")
|
# This regex is not strict enough, but the correct one is too complicated for cmake matching.
|
||||||
set(OSRM_VERSION_MAJOR ${CMAKE_MATCH_1})
|
# https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
|
||||||
set(OSRM_VERSION_MINOR ${CMAKE_MATCH_2})
|
if (packagejson.version MATCHES "^([0-9]+)\.([0-9]+)\.([0-9]+)([-+][0-9a-zA-Z.-]+)?$")
|
||||||
set(OSRM_VERSION_PATCH ${CMAKE_MATCH_3})
|
set(OSRM_VERSION_MAJOR ${CMAKE_MATCH_1})
|
||||||
|
set(OSRM_VERSION_MINOR ${CMAKE_MATCH_2})
|
||||||
|
set(OSRM_VERSION_PATCH ${CMAKE_MATCH_3})
|
||||||
|
set(OSRM_VERSION_PRERELEASE_BUILD ${CMAKE_MATCH_4})
|
||||||
|
|
||||||
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
|
set(OSRM_VERSION packagejson.version)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Version from package.json cannot be parsed, expected semver compatible X.Y.Z, but found ${packagejson.version}")
|
message(FATAL_ERROR "Version from package.json cannot be parsed, expected semver compatible label, but found ${packagejson.version}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
@@ -115,15 +115,14 @@ include(GNUInstallDirs)
|
|||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
message(STATUS "Building on a 64 bit system")
|
message(STATUS "Building on a 64 bit system")
|
||||||
else()
|
else()
|
||||||
message(STATUS "Building on a 32 bit system")
|
message(FATAL_ERROR "Building on a 32 bit system is not supported")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/)
|
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/)
|
||||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
||||||
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sol2-3.3.0/include)
|
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sol2/include)
|
||||||
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/variant/include)
|
|
||||||
|
|
||||||
set(BOOST_COMPONENTS date_time chrono filesystem iostreams program_options regex system thread unit_test_framework)
|
set(BOOST_COMPONENTS date_time iostreams program_options thread unit_test_framework)
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/util/version.hpp.in
|
${CMAKE_CURRENT_SOURCE_DIR}/include/util/version.hpp.in
|
||||||
@@ -151,7 +150,7 @@ add_library(UPDATER OBJECT ${UpdaterGlob})
|
|||||||
add_library(STORAGE OBJECT ${StorageGlob})
|
add_library(STORAGE OBJECT ${StorageGlob})
|
||||||
add_library(ENGINE OBJECT ${EngineGlob})
|
add_library(ENGINE OBJECT ${EngineGlob})
|
||||||
|
|
||||||
if (BUILD_ROUTED)
|
if (BUILD_ROUTED)
|
||||||
add_library(SERVER OBJECT ${ServerGlob})
|
add_library(SERVER OBJECT ${ServerGlob})
|
||||||
add_executable(osrm-routed src/tools/routed.cpp $<TARGET_OBJECTS:SERVER> $<TARGET_OBJECTS:UTIL>)
|
add_executable(osrm-routed src/tools/routed.cpp $<TARGET_OBJECTS:SERVER> $<TARGET_OBJECTS:UTIL>)
|
||||||
endif()
|
endif()
|
||||||
@@ -223,7 +222,7 @@ endif()
|
|||||||
set(MAYBE_COVERAGE_LIBRARIES "")
|
set(MAYBE_COVERAGE_LIBRARIES "")
|
||||||
if (ENABLE_COVERAGE)
|
if (ENABLE_COVERAGE)
|
||||||
if (NOT CMAKE_BUILD_TYPE MATCHES "Debug")
|
if (NOT CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||||
message(ERROR "ENABLE_COVERAGE=ON only make sense with a Debug build")
|
message(ERROR "ENABLE_COVERAGE=ON only makes sense with a Debug build")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "Enabling coverage")
|
message(STATUS "Enabling coverage")
|
||||||
set(MAYBE_COVERAGE_LIBRARIES "-lgcov")
|
set(MAYBE_COVERAGE_LIBRARIES "-lgcov")
|
||||||
@@ -267,7 +266,6 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
|||||||
add_dependency_defines(-DBOOST_LIB_DIAGNOSTIC)
|
add_dependency_defines(-DBOOST_LIB_DIAGNOSTIC)
|
||||||
add_dependency_defines(-D_CRT_SECURE_NO_WARNINGS)
|
add_dependency_defines(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
add_dependency_defines(-DNOMINMAX) # avoid min and max macros that can break compilation
|
add_dependency_defines(-DNOMINMAX) # avoid min and max macros that can break compilation
|
||||||
add_dependency_defines(-D_USE_MATH_DEFINES) #needed for M_PI with cmath.h
|
|
||||||
add_dependency_defines(-D_WIN32_WINNT=0x0501)
|
add_dependency_defines(-D_WIN32_WINNT=0x0501)
|
||||||
add_dependency_defines(-DXML_STATIC)
|
add_dependency_defines(-DXML_STATIC)
|
||||||
find_library(ws2_32_LIBRARY_PATH ws2_32)
|
find_library(ws2_32_LIBRARY_PATH ws2_32)
|
||||||
@@ -309,10 +307,10 @@ add_subdirectory(${FLATBUFFERS_SRC_DIR}
|
|||||||
${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build
|
${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build
|
||||||
EXCLUDE_FROM_ALL)
|
EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
set(FMT_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/fmt-9.1.0/include")
|
set(FMT_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/fmt/include")
|
||||||
add_compile_definitions(FMT_HEADER_ONLY)
|
add_compile_definitions(FMT_HEADER_ONLY)
|
||||||
include_directories(SYSTEM ${FMT_INCLUDE_DIR})
|
include_directories(SYSTEM ${FMT_INCLUDE_DIR})
|
||||||
|
|
||||||
|
|
||||||
# see https://stackoverflow.com/questions/70898030/boost-link-error-using-conan-find-package
|
# see https://stackoverflow.com/questions/70898030/boost-link-error-using-conan-find-package
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
@@ -322,45 +320,44 @@ endif()
|
|||||||
if(ENABLE_CONAN)
|
if(ENABLE_CONAN)
|
||||||
message(STATUS "Installing dependencies via Conan")
|
message(STATUS "Installing dependencies via Conan")
|
||||||
|
|
||||||
# Conan will generate Find*.cmake files to build directory, so we use them with the highest priority
|
# Conan will generate Find*.cmake files to build directory, so we use them with the highest priority
|
||||||
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_BINARY_DIR})
|
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_BINARY_DIR})
|
||||||
list(INSERT CMAKE_PREFIX_PATH 0 ${CMAKE_BINARY_DIR})
|
list(INSERT CMAKE_PREFIX_PATH 0 ${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/conan.cmake)
|
include(${CMAKE_CURRENT_LIST_DIR}/cmake/conan.cmake)
|
||||||
|
|
||||||
set(CONAN_BOOST_VERSION "1.79.0#96e4902111a2e343a8ba0aa95391bb58")
|
conan_check(REQUIRED)
|
||||||
set(CONAN_BZIP2_VERSION "1.0.8#d1b2d5816f25865acf978501dff1f897")
|
|
||||||
set(CONAN_EXPAT_VERSION "2.2.10#916908d4a570ad839edd25322c3268cd")
|
set(CONAN_BOOST_VERSION "1.85.0@#14265ec82b25d91305bbb3b30d3357f8")
|
||||||
set(CONAN_LUA_VERSION "5.4.4#3ec62efc37cd0a5d80b9e5cb35277360")
|
set(CONAN_BZIP2_VERSION "1.0.8@#d1b2d5816f25865acf978501dff1f897")
|
||||||
set(CONAN_TBB_VERSION "2021.3.0#507ec17cbd51a84167e143b20d170eea")
|
set(CONAN_EXPAT_VERSION "2.6.2@#2d385d0d50eb5561006a7ff9e356656b")
|
||||||
|
set(CONAN_LUA_VERSION "5.4.6@#658d6089093cf01992c2737ab2e96763")
|
||||||
|
set(CONAN_TBB_VERSION "2021.12.0@#e56e5b44be8d690530585dd3634c0106")
|
||||||
|
|
||||||
set(CONAN_SYSTEM_INCLUDES ON)
|
set(CONAN_SYSTEM_INCLUDES ON)
|
||||||
|
|
||||||
# TODO:
|
|
||||||
# if we link TBB dynamically osrm-extract.exe finishes on the first access to any TBB symbol
|
|
||||||
# with exit code = -1073741515, which means that program cannot load required DLL.
|
|
||||||
if (MSVC)
|
|
||||||
set(TBB_SHARED False)
|
|
||||||
else()
|
|
||||||
set(TBB_SHARED True)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CONAN_ARGS
|
set(CONAN_ARGS
|
||||||
REQUIRES
|
REQUIRES
|
||||||
"boost/${CONAN_BOOST_VERSION}"
|
"boost/${CONAN_BOOST_VERSION}"
|
||||||
"bzip2/${CONAN_BZIP2_VERSION}"
|
"bzip2/${CONAN_BZIP2_VERSION}"
|
||||||
"expat/${CONAN_EXPAT_VERSION}"
|
"expat/${CONAN_EXPAT_VERSION}"
|
||||||
"lua/${CONAN_LUA_VERSION}"
|
"lua/${CONAN_LUA_VERSION}"
|
||||||
"onetbb/${CONAN_TBB_VERSION}"
|
"onetbb/${CONAN_TBB_VERSION}"
|
||||||
BASIC_SETUP
|
BASIC_SETUP
|
||||||
GENERATORS cmake_find_package json # json generator generates a conanbuildinfo.json in the build folder so (non-CMake) projects can easily parse OSRM's dependencies
|
GENERATORS cmake_find_package json # json generator generates a conanbuildinfo.json in the build folder so (non-CMake) projects can easily parse OSRM's dependencies
|
||||||
KEEP_RPATHS
|
KEEP_RPATHS
|
||||||
NO_OUTPUT_DIRS
|
NO_OUTPUT_DIRS
|
||||||
OPTIONS boost:filesystem_version=3 # https://stackoverflow.com/questions/73392648/error-with-boost-filesystem-version-in-cmake
|
OPTIONS boost:without_stacktrace=True # Apple Silicon cross-compilation fails without it
|
||||||
onetbb:shared=${TBB_SHARED}
|
|
||||||
boost:without_stacktrace=True # Apple Silicon cross-compilation fails without it
|
|
||||||
BUILD missing
|
BUILD missing
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Enable revisions in the conan config
|
||||||
|
execute_process(COMMAND ${CONAN_CMD} config set general.revisions_enabled=1 RESULT_VARIABLE RET_CODE)
|
||||||
|
if(NOT "${RET_CODE}" STREQUAL "0")
|
||||||
|
message(FATAL_ERROR "Error setting revisions for Conan: '${RET_CODE}'")
|
||||||
|
endif()
|
||||||
|
|
||||||
# explicitly say Conan to use x86 dependencies if build for x86 platforms (https://github.com/conan-io/cmake-conan/issues/141)
|
# explicitly say Conan to use x86 dependencies if build for x86 platforms (https://github.com/conan-io/cmake-conan/issues/141)
|
||||||
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
conan_cmake_run("${CONAN_ARGS};ARCH;x86")
|
conan_cmake_run("${CONAN_ARGS};ARCH;x86")
|
||||||
@@ -380,16 +377,12 @@ if(ENABLE_CONAN)
|
|||||||
set(Boost_USE_STATIC_LIBS ON)
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||||
set(Boost_DATE_TIME_LIBRARY "${Boost_date_time_LIB_TARGETS}")
|
set(Boost_DATE_TIME_LIBRARY "${Boost_date_time_LIB_TARGETS}")
|
||||||
set(Boost_CHRONO_LIBRARY "${Boost_chrono_LIB_TARGETS}")
|
|
||||||
set(Boost_PROGRAM_OPTIONS_LIBRARY "${Boost_program_options_LIB_TARGETS}")
|
set(Boost_PROGRAM_OPTIONS_LIBRARY "${Boost_program_options_LIB_TARGETS}")
|
||||||
set(Boost_FILESYSTEM_LIBRARY "${Boost_filesystem_LIB_TARGETS}")
|
|
||||||
set(Boost_IOSTREAMS_LIBRARY "${Boost_iostreams_LIB_TARGETS}")
|
set(Boost_IOSTREAMS_LIBRARY "${Boost_iostreams_LIB_TARGETS}")
|
||||||
set(Boost_THREAD_LIBRARY "${Boost_thread_LIB_TARGETS}")
|
set(Boost_THREAD_LIBRARY "${Boost_thread_LIB_TARGETS}")
|
||||||
set(Boost_SYSTEM_LIBRARY "${Boost_system_LIB_TARGETS}")
|
|
||||||
set(Boost_ZLIB_LIBRARY "${Boost_zlib_LIB_TARGETS}")
|
set(Boost_ZLIB_LIBRARY "${Boost_zlib_LIB_TARGETS}")
|
||||||
set(Boost_REGEX_LIBRARY "${Boost_regex_LIB_TARGETS}")
|
|
||||||
set(Boost_UNIT_TEST_FRAMEWORK_LIBRARY "${Boost_unit_test_framework_LIB_TARGETS}")
|
set(Boost_UNIT_TEST_FRAMEWORK_LIBRARY "${Boost_unit_test_framework_LIB_TARGETS}")
|
||||||
|
|
||||||
|
|
||||||
find_package(BZip2 REQUIRED)
|
find_package(BZip2 REQUIRED)
|
||||||
find_package(EXPAT REQUIRED)
|
find_package(EXPAT REQUIRED)
|
||||||
@@ -460,18 +453,17 @@ add_dependency_includes(${ZLIB_INCLUDE_DIRS})
|
|||||||
|
|
||||||
add_dependency_defines(-DBOOST_SPIRIT_USE_PHOENIX_V3)
|
add_dependency_defines(-DBOOST_SPIRIT_USE_PHOENIX_V3)
|
||||||
add_dependency_defines(-DBOOST_RESULT_OF_USE_DECLTYPE)
|
add_dependency_defines(-DBOOST_RESULT_OF_USE_DECLTYPE)
|
||||||
add_dependency_defines(-DBOOST_FILESYSTEM_NO_DEPRECATED)
|
|
||||||
|
# Workaround for https://github.com/boostorg/phoenix/issues/111
|
||||||
|
add_dependency_defines(-DBOOST_PHOENIX_STL_TUPLE_H_)
|
||||||
|
|
||||||
add_definitions(${OSRM_DEFINES})
|
add_definitions(${OSRM_DEFINES})
|
||||||
include_directories(SYSTEM ${DEPENDENCIES_INCLUDE_DIRS})
|
include_directories(SYSTEM ${DEPENDENCIES_INCLUDE_DIRS})
|
||||||
|
|
||||||
set(BOOST_BASE_LIBRARIES
|
set(BOOST_BASE_LIBRARIES
|
||||||
${Boost_DATE_TIME_LIBRARY}
|
${Boost_DATE_TIME_LIBRARY}
|
||||||
${Boost_CHRONO_LIBRARY}
|
|
||||||
${Boost_FILESYSTEM_LIBRARY}
|
|
||||||
${Boost_IOSTREAMS_LIBRARY}
|
${Boost_IOSTREAMS_LIBRARY}
|
||||||
${Boost_THREAD_LIBRARY}
|
${Boost_THREAD_LIBRARY})
|
||||||
${Boost_SYSTEM_LIBRARY})
|
|
||||||
|
|
||||||
set(BOOST_ENGINE_LIBRARIES
|
set(BOOST_ENGINE_LIBRARIES
|
||||||
${Boost_ZLIB_LIBRARY}
|
${Boost_ZLIB_LIBRARY}
|
||||||
@@ -490,7 +482,6 @@ endif()
|
|||||||
|
|
||||||
set(EXTRACTOR_LIBRARIES
|
set(EXTRACTOR_LIBRARIES
|
||||||
${BZIP2_LIBRARIES}
|
${BZIP2_LIBRARIES}
|
||||||
${Boost_REGEX_LIBRARY}
|
|
||||||
${BOOST_BASE_LIBRARIES}
|
${BOOST_BASE_LIBRARIES}
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
${EXPAT_LIBRARIES}
|
${EXPAT_LIBRARIES}
|
||||||
@@ -595,7 +586,6 @@ if (BUILD_ROUTED)
|
|||||||
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
|
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
file(GLOB VariantGlob third_party/variant/include/mapbox/*.hpp)
|
|
||||||
file(GLOB FlatbuffersGlob third_party/flatbuffers/include/flatbuffers/*.h)
|
file(GLOB FlatbuffersGlob third_party/flatbuffers/include/flatbuffers/*.h)
|
||||||
file(GLOB LibraryGlob include/osrm/*.hpp)
|
file(GLOB LibraryGlob include/osrm/*.hpp)
|
||||||
file(GLOB ParametersGlob include/engine/api/*_parameters.hpp)
|
file(GLOB ParametersGlob include/engine/api/*_parameters.hpp)
|
||||||
@@ -615,7 +605,6 @@ install(FILES ${ContractorHeader} DESTINATION include/osrm/contractor)
|
|||||||
install(FILES ${LibraryGlob} DESTINATION include/osrm)
|
install(FILES ${LibraryGlob} DESTINATION include/osrm)
|
||||||
install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api)
|
install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api)
|
||||||
install(FILES ${ApiHeader} DESTINATION include/osrm/engine/api)
|
install(FILES ${ApiHeader} DESTINATION include/osrm/engine/api)
|
||||||
install(FILES ${VariantGlob} DESTINATION include/mapbox)
|
|
||||||
install(FILES ${FlatbuffersGlob} DESTINATION include/flatbuffers)
|
install(FILES ${FlatbuffersGlob} DESTINATION include/flatbuffers)
|
||||||
install(TARGETS osrm-extract DESTINATION bin)
|
install(TARGETS osrm-extract DESTINATION bin)
|
||||||
install(TARGETS osrm-partition DESTINATION bin)
|
install(TARGETS osrm-partition DESTINATION bin)
|
||||||
@@ -639,6 +628,10 @@ install(TARGETS osrm_guidance DESTINATION lib)
|
|||||||
set(DefaultProfilesDir profiles)
|
set(DefaultProfilesDir profiles)
|
||||||
install(DIRECTORY ${DefaultProfilesDir} DESTINATION share/osrm)
|
install(DIRECTORY ${DefaultProfilesDir} DESTINATION share/osrm)
|
||||||
|
|
||||||
|
# Install data geojson files to /usr/local/share/osrm/data by default
|
||||||
|
set(DefaultProfilesDir data)
|
||||||
|
install(DIRECTORY ${DefaultProfilesDir} DESTINATION share/osrm)
|
||||||
|
|
||||||
# Setup exporting variables for pkgconfig and subproject
|
# Setup exporting variables for pkgconfig and subproject
|
||||||
#
|
#
|
||||||
|
|
||||||
@@ -733,23 +726,23 @@ if (ENABLE_FUZZING)
|
|||||||
add_subdirectory(fuzz)
|
add_subdirectory(fuzz)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# add headers sanity check target that includes all headers independently
|
# add headers sanity check target that includes all headers independently
|
||||||
set(check_headers_dir "${PROJECT_BINARY_DIR}/check-headers")
|
set(check_headers_dir "${PROJECT_BINARY_DIR}/check-headers")
|
||||||
file(GLOB_RECURSE headers_to_check
|
file(GLOB_RECURSE headers_to_check
|
||||||
${PROJECT_BINARY_DIR}/*.hpp
|
${PROJECT_BINARY_DIR}/*.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/*.hpp)
|
${PROJECT_SOURCE_DIR}/include/*.hpp)
|
||||||
foreach(header ${headers_to_check})
|
foreach(header ${headers_to_check})
|
||||||
if ("${header}" MATCHES ".*/include/nodejs/.*")
|
if ("${header}" MATCHES ".*/include/nodejs/.*")
|
||||||
# we do not check NodeJS bindings headers
|
# we do not check NodeJS bindings headers
|
||||||
continue()
|
continue()
|
||||||
endif()
|
endif()
|
||||||
get_filename_component(filename ${header} NAME_WE)
|
get_filename_component(filename ${header} NAME_WE)
|
||||||
set(filename "${check_headers_dir}/${filename}.cpp")
|
set(filename "${check_headers_dir}/${filename}.cpp")
|
||||||
if (NOT EXISTS ${filename})
|
if (NOT EXISTS ${filename})
|
||||||
file(WRITE ${filename} "#include \"${header}\"\n")
|
file(WRITE ${filename} "#include \"${header}\"\n")
|
||||||
endif()
|
endif()
|
||||||
list(APPEND sources ${filename})
|
list(APPEND sources ${filename})
|
||||||
endforeach()
|
endforeach()
|
||||||
add_library(check-headers STATIC EXCLUDE_FROM_ALL ${sources})
|
add_library(check-headers STATIC EXCLUDE_FROM_ALL ${sources})
|
||||||
set_target_properties(check-headers PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${check_headers_dir})
|
set_target_properties(check-headers PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${check_headers_dir})
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ You can add a :+1: emoji reaction to the issue if you want to express interest i
|
|||||||
|
|
||||||
# Developer
|
# Developer
|
||||||
|
|
||||||
We use `clang-format` version `3.8` to consistently format the code base. There is a helper script under `scripts/format.sh`.
|
We use `clang-format` version `15` to consistently format the code base. There is a helper script under `scripts/format.sh`.
|
||||||
The format is automatically checked by the `mason-linux-release` job of a Travis CI build.
|
The format is automatically checked by the `mason-linux-release` job of a Travis CI build.
|
||||||
To save development time a local hook `.git/hooks/pre-push`
|
To save development time a local hook `.git/hooks/pre-push`
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ The following services are available via HTTP API, C++ library interface and Nod
|
|||||||
|
|
||||||
To quickly try OSRM use our [demo server](http://map.project-osrm.org) which comes with both the backend and a frontend on top.
|
To quickly try OSRM use our [demo server](http://map.project-osrm.org) which comes with both the backend and a frontend on top.
|
||||||
|
|
||||||
For a quick introduction about how the road network is represented in OpenStreetMap and how to map specific road network features have a look at [this guide about mapping for navigation](https://www.mapbox.com/mapping/mapping-for-navigation/).
|
For a quick introduction about how the road network is represented in OpenStreetMap and how to map specific road network features have a look at [the OSM wiki on routing](https://wiki.openstreetmap.org/wiki/Routing) or [this guide about mapping for navigation](https://web.archive.org/web/20221206013651/https://labs.mapbox.com/mapping/mapping-for-navigation/).
|
||||||
|
|
||||||
Related [Project-OSRM](https://github.com/Project-OSRM) repositories:
|
Related [Project-OSRM](https://github.com/Project-OSRM) repositories:
|
||||||
- [osrm-frontend](https://github.com/Project-OSRM/osrm-frontend) - User-facing frontend with map. The demo server runs this on top of the backend
|
- [osrm-frontend](https://github.com/Project-OSRM/osrm-frontend) - User-facing frontend with map. The demo server runs this on top of the backend
|
||||||
- [osrm-text-instructions](https://github.com/Project-OSRM/osrm-text-instructions) - Text instructions from OSRM route response
|
- [osrm-text-instructions](https://github.com/Project-OSRM/osrm-text-instructions) - Text instructions from OSRM route response
|
||||||
- [osrm-backend-docker](https://hub.docker.com/r/osrm/osrm-backend/) - Ready to use Docker images
|
- [osrm-backend-docker](https://github.com/project-osrm/osrm-backend/pkgs/container/osrm-backend) - Ready to use Docker images
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
os: Visual Studio 2019
|
|
||||||
|
|
||||||
# clone directory
|
|
||||||
clone_folder: c:\projects\osrm
|
|
||||||
|
|
||||||
platform: x64
|
|
||||||
|
|
||||||
# no-op for the time being until someone with access to GitHub checks settings will remove integration with AppVeyor
|
|
||||||
# https://github.com/Project-OSRM/osrm-backend/pull/6312#issuecomment-1217237055
|
|
||||||
build_script:
|
|
||||||
- EXIT 0
|
|
||||||
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
@ECHO OFF
|
|
||||||
SETLOCAL
|
|
||||||
SET EL=0
|
|
||||||
|
|
||||||
ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
SET PLATFORM=x64
|
|
||||||
SET CONFIGURATION=Release
|
|
||||||
::SET LOCAL_DEV=1
|
|
||||||
|
|
||||||
FOR /F "tokens=*" %%i in ('git rev-parse --abbrev-ref HEAD') do SET APPVEYOR_REPO_BRANCH=%%i
|
|
||||||
ECHO APPVEYOR_REPO_BRANCH^: %APPVEYOR_REPO_BRANCH%
|
|
||||||
|
|
||||||
SET PATH=C:\Program Files\7-Zip;%PATH%
|
|
||||||
|
|
||||||
powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force
|
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
|
||||||
CALL appveyor-build.bat
|
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
|
||||||
|
|
||||||
GOTO DONE
|
|
||||||
|
|
||||||
|
|
||||||
:ERROR
|
|
||||||
ECHO ~~~~~~~~~~~~~~~~~~~~~~ ERROR %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
ECHO ERRORLEVEL^: %ERRORLEVEL%
|
|
||||||
SET EL=%ERRORLEVEL%
|
|
||||||
|
|
||||||
:DONE
|
|
||||||
ECHO ~~~~~~~~~~~~~~~~~~~~~~ DONE %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
EXIT /b %EL%
|
|
||||||
+1
-1
@@ -55,7 +55,7 @@ function(_get_msvc_ide_version result)
|
|||||||
set(${result} 15 PARENT_SCOPE)
|
set(${result} 15 PARENT_SCOPE)
|
||||||
elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930)
|
elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930)
|
||||||
set(${result} 16 PARENT_SCOPE)
|
set(${result} 16 PARENT_SCOPE)
|
||||||
elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1940)
|
elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1950)
|
||||||
set(${result} 17 PARENT_SCOPE)
|
set(${result} 17 PARENT_SCOPE)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]")
|
message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]")
|
||||||
|
|||||||
+8
-15
@@ -50,9 +50,7 @@ add_warning(all)
|
|||||||
add_warning(extra)
|
add_warning(extra)
|
||||||
add_warning(pedantic)
|
add_warning(pedantic)
|
||||||
add_warning(error) # treat all warnings as errors
|
add_warning(error) # treat all warnings as errors
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||||
add_warning(strict-overflow=2)
|
|
||||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
|
||||||
add_warning(strict-overflow=1)
|
add_warning(strict-overflow=1)
|
||||||
endif()
|
endif()
|
||||||
add_warning(suggest-override)
|
add_warning(suggest-override)
|
||||||
@@ -79,15 +77,10 @@ add_warning(sizeof-array-argument)
|
|||||||
add_warning(switch-bool)
|
add_warning(switch-bool)
|
||||||
add_warning(tautological-compare)
|
add_warning(tautological-compare)
|
||||||
add_warning(trampolines)
|
add_warning(trampolines)
|
||||||
no_warning(c++17-extensions)
|
# these warnings are not enabled by default
|
||||||
# TODO: these warnings are not enabled by default, but we consider them as useful and good to enable in the future
|
# no_warning(name-of-warning)
|
||||||
no_warning(implicit-int-conversion)
|
no_warning(deprecated-comma-subscript)
|
||||||
no_warning(implicit-float-conversion)
|
no_warning(comma-subscript)
|
||||||
no_warning(unused-member-function)
|
no_warning(ambiguous-reversed-operator)
|
||||||
no_warning(old-style-cast)
|
no_warning(restrict)
|
||||||
no_warning(non-virtual-dtor)
|
no_warning(free-nonheap-object)
|
||||||
no_warning(float-conversion)
|
|
||||||
no_warning(sign-conversion)
|
|
||||||
no_warning(shorten-64-to-32)
|
|
||||||
no_warning(padded)
|
|
||||||
no_warning(missing-noreturn)
|
|
||||||
|
|||||||
+1
-3
@@ -3,7 +3,5 @@ module.exports = {
|
|||||||
ch: '--strict --tags ~@stress --tags ~@todo --tags ~@mld -f progress --require features/support --require features/step_definitions',
|
ch: '--strict --tags ~@stress --tags ~@todo --tags ~@mld -f progress --require features/support --require features/step_definitions',
|
||||||
todo: '--strict --tags @todo --require features/support --require features/step_definitions',
|
todo: '--strict --tags @todo --require features/support --require features/step_definitions',
|
||||||
all: '--strict --require features/support --require features/step_definitions',
|
all: '--strict --require features/support --require features/step_definitions',
|
||||||
mld: '--strict --tags ~@stress --tags ~@todo --tags ~@ch --require features/support --require features/step_definitions -f progress',
|
mld: '--strict --tags ~@stress --tags ~@todo --tags ~@ch --require features/support --require features/step_definitions -f progress'
|
||||||
verify_routed_js: '--strict --tags ~@skip_on_routed_js --tags ~@stress --tags ~@todo --tags ~@mld-only -f progress --require features/support --require features/step_definitions',
|
|
||||||
mld_routed_js: '--strict --tags ~@skip_on_routed_js --tags ~@stress --tags ~@todo --tags ~@ch --require features/support --require features/step_definitions -f progress',
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
FROM debian:bullseye-slim as builder
|
|
||||||
ARG DOCKER_TAG
|
|
||||||
ARG BUILD_CONCURRENCY
|
|
||||||
RUN mkdir -p /src && mkdir -p /opt
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get -y --no-install-recommends install ca-certificates cmake make git gcc g++ libbz2-dev libxml2-dev wget \
|
|
||||||
libzip-dev libboost1.74-all-dev lua5.4 liblua5.4-dev pkg-config -o APT::Install-Suggests=0 -o APT::Install-Recommends=0
|
|
||||||
|
|
||||||
RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
|
|
||||||
ldconfig /usr/local/lib && \
|
|
||||||
git clone --branch v2021.3.0 --single-branch https://github.com/oneapi-src/oneTBB.git && \
|
|
||||||
cd oneTBB && \
|
|
||||||
mkdir build && \
|
|
||||||
cd build && \
|
|
||||||
cmake -DTBB_TEST=OFF -DCMAKE_BUILD_TYPE=Release .. && \
|
|
||||||
cmake --build . && \
|
|
||||||
cmake --install .
|
|
||||||
|
|
||||||
COPY . /src
|
|
||||||
WORKDIR /src
|
|
||||||
|
|
||||||
RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
|
|
||||||
echo "Building OSRM ${DOCKER_TAG}" && \
|
|
||||||
git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \
|
|
||||||
echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \
|
|
||||||
mkdir -p build && \
|
|
||||||
cd build && \
|
|
||||||
BUILD_TYPE="Release" && \
|
|
||||||
ENABLE_ASSERTIONS="Off" && \
|
|
||||||
BUILD_TOOLS="Off" && \
|
|
||||||
case ${DOCKER_TAG} in *"-debug"*) BUILD_TYPE="Debug";; esac && \
|
|
||||||
case ${DOCKER_TAG} in *"-assertions"*) BUILD_TYPE="RelWithDebInfo" && ENABLE_ASSERTIONS="On" && BUILD_TOOLS="On";; esac && \
|
|
||||||
echo "Building ${BUILD_TYPE} with ENABLE_ASSERTIONS=${ENABLE_ASSERTIONS} BUILD_TOOLS=${BUILD_TOOLS}" && \
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS} -DBUILD_TOOLS=${BUILD_TOOLS} -DENABLE_LTO=On && \
|
|
||||||
make -j${NPROC} install && \
|
|
||||||
cd ../profiles && \
|
|
||||||
cp -r * /opt && \
|
|
||||||
strip /usr/local/bin/* && \
|
|
||||||
rm -rf /src
|
|
||||||
|
|
||||||
|
|
||||||
# Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
|
|
||||||
# Only the content below ends up in the image, this helps remove /src from the image (which is large)
|
|
||||||
FROM debian:bullseye-slim as runstage
|
|
||||||
|
|
||||||
COPY --from=builder /usr/local /usr/local
|
|
||||||
COPY --from=builder /opt /opt
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get install -y --no-install-recommends libboost-program-options1.74.0 libboost-regex1.74.0 \
|
|
||||||
libboost-date-time1.74.0 libboost-chrono1.74.0 libboost-filesystem1.74.0 \
|
|
||||||
libboost-iostreams1.74.0 libboost-system1.74.0 libboost-thread1.74.0 \
|
|
||||||
expat liblua5.4-0 && \
|
|
||||||
rm -rf /var/lib/apt/lists/* && \
|
|
||||||
# add /usr/local/lib to ldconfig to allow loading libraries from there
|
|
||||||
ldconfig /usr/local/lib
|
|
||||||
|
|
||||||
RUN /usr/local/bin/osrm-extract --help && \
|
|
||||||
/usr/local/bin/osrm-routed --help && \
|
|
||||||
/usr/local/bin/osrm-contract --help && \
|
|
||||||
/usr/local/bin/osrm-partition --help && \
|
|
||||||
/usr/local/bin/osrm-customize --help
|
|
||||||
|
|
||||||
WORKDIR /opt
|
|
||||||
|
|
||||||
EXPOSE 5000
|
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
Dockerfile-debian
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
FROM alpine:3.20.0 as alpine-mimalloc
|
||||||
|
|
||||||
|
RUN apk add --no-cache mimalloc
|
||||||
|
|
||||||
|
ENV LD_PRELOAD=/usr/lib/libmimalloc.so.2
|
||||||
|
ENV MIMALLOC_LARGE_OS_PAGES=1
|
||||||
|
|
||||||
|
|
||||||
|
FROM alpine-mimalloc as builder
|
||||||
|
ARG DOCKER_TAG
|
||||||
|
ARG BUILD_CONCURRENCY
|
||||||
|
RUN mkdir -p /src && mkdir -p /opt
|
||||||
|
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
cmake make git clang libbz2 libxml2 \
|
||||||
|
boost-dev boost-program_options boost-filesystem boost-iostreams boost-thread \
|
||||||
|
lua5.4-dev onetbb-dev expat-dev
|
||||||
|
|
||||||
|
COPY . /src
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
|
||||||
|
echo "Building OSRM ${DOCKER_TAG}" && \
|
||||||
|
git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \
|
||||||
|
echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \
|
||||||
|
mkdir -p build && \
|
||||||
|
cd build && \
|
||||||
|
BUILD_TYPE="Release" && \
|
||||||
|
ENABLE_ASSERTIONS="Off" && \
|
||||||
|
BUILD_TOOLS="Off" && \
|
||||||
|
case ${DOCKER_TAG} in *"-debug"*) BUILD_TYPE="Debug";; esac && \
|
||||||
|
case ${DOCKER_TAG} in *"-assertions"*) BUILD_TYPE="RelWithDebInfo" && ENABLE_ASSERTIONS="On" && BUILD_TOOLS="On";; esac && \
|
||||||
|
echo "Building ${BUILD_TYPE} with ENABLE_ASSERTIONS=${ENABLE_ASSERTIONS} BUILD_TOOLS=${BUILD_TOOLS}" && \
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS} -DBUILD_TOOLS=${BUILD_TOOLS} -DENABLE_LTO=On && \
|
||||||
|
make -j${NPROC} install && \
|
||||||
|
cd ../profiles && \
|
||||||
|
cp -r * /opt && \
|
||||||
|
strip /usr/local/bin/* && \
|
||||||
|
rm -rf /src
|
||||||
|
|
||||||
|
|
||||||
|
# Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
|
||||||
|
# Only the content below ends up in the image, this helps remove /src from the image (which is large)
|
||||||
|
FROM alpine-mimalloc as runstage
|
||||||
|
|
||||||
|
COPY --from=builder /usr/local /usr/local
|
||||||
|
COPY --from=builder /opt /opt
|
||||||
|
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
boost-program_options boost-date_time boost-iostreams boost-thread \
|
||||||
|
expat lua5.4 onetbb && \
|
||||||
|
ldconfig /usr/local/lib
|
||||||
|
|
||||||
|
RUN /usr/local/bin/osrm-extract --help && \
|
||||||
|
/usr/local/bin/osrm-routed --help && \
|
||||||
|
/usr/local/bin/osrm-contract --help && \
|
||||||
|
/usr/local/bin/osrm-partition --help && \
|
||||||
|
/usr/local/bin/osrm-customize --help
|
||||||
|
|
||||||
|
WORKDIR /opt
|
||||||
|
|
||||||
|
EXPOSE 5000
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
FROM debian:bookworm-slim as builder
|
||||||
|
ARG DOCKER_TAG
|
||||||
|
ARG BUILD_CONCURRENCY
|
||||||
|
RUN mkdir -p /src && mkdir -p /opt
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get -y --no-install-recommends install ca-certificates cmake make git gcc g++ libbz2-dev libxml2-dev wget \
|
||||||
|
libzip-dev libboost1.81-all-dev lua5.4 liblua5.4-dev pkg-config -o APT::Install-Suggests=0 -o APT::Install-Recommends=0
|
||||||
|
|
||||||
|
RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
|
||||||
|
ldconfig /usr/local/lib && \
|
||||||
|
git clone --branch v2021.12.0 --single-branch https://github.com/oneapi-src/oneTBB.git && \
|
||||||
|
cd oneTBB && \
|
||||||
|
mkdir build && \
|
||||||
|
cd build && \
|
||||||
|
cmake -DTBB_TEST=OFF -DCMAKE_BUILD_TYPE=Release .. && \
|
||||||
|
cmake --build . && \
|
||||||
|
cmake --install .
|
||||||
|
|
||||||
|
COPY . /src
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
|
||||||
|
export CXXFLAGS="-Wno-array-bounds -Wno-uninitialized" && \
|
||||||
|
echo "Building OSRM ${DOCKER_TAG}" && \
|
||||||
|
git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \
|
||||||
|
echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \
|
||||||
|
mkdir -p build && \
|
||||||
|
cd build && \
|
||||||
|
BUILD_TYPE="Release" && \
|
||||||
|
ENABLE_ASSERTIONS="Off" && \
|
||||||
|
BUILD_TOOLS="Off" && \
|
||||||
|
case ${DOCKER_TAG} in *"-debug"*) BUILD_TYPE="Debug";; esac && \
|
||||||
|
case ${DOCKER_TAG} in *"-assertions"*) BUILD_TYPE="RelWithDebInfo" && ENABLE_ASSERTIONS="On" && BUILD_TOOLS="On";; esac && \
|
||||||
|
echo "Building ${BUILD_TYPE} with ENABLE_ASSERTIONS=${ENABLE_ASSERTIONS} BUILD_TOOLS=${BUILD_TOOLS}" && \
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS} -DBUILD_TOOLS=${BUILD_TOOLS} -DENABLE_LTO=On && \
|
||||||
|
make -j${NPROC} install && \
|
||||||
|
cd ../profiles && \
|
||||||
|
cp -r * /opt && \
|
||||||
|
strip /usr/local/bin/* && \
|
||||||
|
rm -rf /src
|
||||||
|
|
||||||
|
|
||||||
|
# Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
|
||||||
|
# Only the content below ends up in the image, this helps remove /src from the image (which is large)
|
||||||
|
FROM debian:bookworm-slim as runstage
|
||||||
|
|
||||||
|
COPY --from=builder /usr/local /usr/local
|
||||||
|
COPY --from=builder /opt /opt
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
libboost-program-options1.81.0 libboost-date-time1.81.0 libboost-iostreams1.81.0 libboost-thread1.81.0 \
|
||||||
|
expat liblua5.4-0 && \
|
||||||
|
rm -rf /var/lib/apt/lists/* && \
|
||||||
|
# add /usr/local/lib to ldconfig to allow loading libraries from there
|
||||||
|
ldconfig /usr/local/lib
|
||||||
|
|
||||||
|
RUN /usr/local/bin/osrm-extract --help && \
|
||||||
|
/usr/local/bin/osrm-routed --help && \
|
||||||
|
/usr/local/bin/osrm-contract --help && \
|
||||||
|
/usr/local/bin/osrm-partition --help && \
|
||||||
|
/usr/local/bin/osrm-customize --help
|
||||||
|
|
||||||
|
WORKDIR /opt
|
||||||
|
|
||||||
|
EXPOSE 5000
|
||||||
Regular → Executable
+5
-1
@@ -6,4 +6,8 @@
|
|||||||
# ensure that "COPY . /src" is referring to the repo root, not the directory
|
# ensure that "COPY . /src" is referring to the repo root, not the directory
|
||||||
# that contains the Dockerfile.
|
# that contains the Dockerfile.
|
||||||
# This script gets executed with a pwd of wherever the Dockerfile is.
|
# This script gets executed with a pwd of wherever the Dockerfile is.
|
||||||
docker build --build-arg BUILD_CONCURRENCY=${CONCURRENCY:-1} --build-arg DOCKER_TAG=${DOCKER_TAG} -t $IMAGE_NAME -f Dockerfile ..
|
|
||||||
|
DOCKER_BUILD="docker build --build-arg BUILD_CONCURRENCY=${CONCURRENCY} --build-arg DOCKER_TAG=${DOCKER_TAG:?unset} -t ${IMAGE_NAME:?unset} -f"
|
||||||
|
|
||||||
|
$DOCKER_BUILD Dockerfile ..
|
||||||
|
$DOCKER_BUILD Dockerfile-alpine ..
|
||||||
|
|||||||
+2
-2
@@ -35,7 +35,7 @@ To pass parameters to each location some options support an array-like encoding:
|
|||||||
|radiuses |`{radius};{radius}[;{radius} ...]` |Limits the search to given radius in meters. |
|
|radiuses |`{radius};{radius}[;{radius} ...]` |Limits the search to given radius in meters. |
|
||||||
|generate\_hints |`true` (default), `false` |Adds a Hint to the response which can be used in subsequent requests, see `hints` parameter. |
|
|generate\_hints |`true` (default), `false` |Adds a Hint to the response which can be used in subsequent requests, see `hints` parameter. |
|
||||||
|hints |`{hint};{hint}[;{hint} ...]` |Hint from previous request to derive position in street network. |
|
|hints |`{hint};{hint}[;{hint} ...]` |Hint from previous request to derive position in street network. |
|
||||||
|approaches |`{approach};{approach}[;{approach} ...]` |Keep waypoints on curbside. |
|
|approaches |`{approach};{approach}[;{approach} ...]` |Restrict the direction on the road network at a waypoint, relative to the input coordinate. |
|
||||||
|exclude |`{class}[,{class}]` |Additive list of classes to avoid, the order does not matter. |
|
|exclude |`{class}[,{class}]` |Additive list of classes to avoid, the order does not matter. |
|
||||||
|snapping |`default` (default), `any` |Default snapping avoids is_startpoint (see profile) edges, `any` will snap to any edge in the graph |
|
|snapping |`default` (default), `any` |Default snapping avoids is_startpoint (see profile) edges, `any` will snap to any edge in the graph |
|
||||||
|skip_waypoints |`true`, `false` (default) |Removes waypoints from the response. Waypoints are still calculated, but not serialized. Could be useful in case you are interested in some other part of the response and do not want to transfer waste data. |
|
|skip_waypoints |`true`, `false` (default) |Removes waypoints from the response. Waypoints are still calculated, but not serialized. Could be useful in case you are interested in some other part of the response and do not want to transfer waste data. |
|
||||||
@@ -47,7 +47,7 @@ Where the elements follow the following format:
|
|||||||
|bearing |`{value},{range}` `integer 0 .. 360,integer 0 .. 180` |
|
|bearing |`{value},{range}` `integer 0 .. 360,integer 0 .. 180` |
|
||||||
|radius |`double >= 0` or `unlimited` (default) |
|
|radius |`double >= 0` or `unlimited` (default) |
|
||||||
|hint |Base64 `string` |
|
|hint |Base64 `string` |
|
||||||
|approach |`curb` or `unrestricted` (default) |
|
|approach |`curb`, `opposite` or `unrestricted` (default) |
|
||||||
|class |A class name determined by the profile or `none`. |
|
|class |A class name determined by the profile or `none`. |
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
+5
-5
@@ -21,7 +21,7 @@ var osrm = new OSRM('network.osrm');
|
|||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `options` **([Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** Options for creating an OSRM object or string to the `.osrm` file. (optional, default `{shared_memory:true}`)
|
- `options` **([Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** Options for creating an OSRM object or string to the `.osrm` file. (optional, default `{shared_memory:true}`)
|
||||||
- `options.algorithm` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The algorithm to use for routing. Can be 'CH', 'CoreCH' or 'MLD'. Default is 'CH'.
|
- `options.algorithm` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The algorithm to use for routing. Can be 'CH', or 'MLD'. Default is 'CH'.
|
||||||
Make sure you prepared the dataset with the correct toolchain.
|
Make sure you prepared the dataset with the correct toolchain.
|
||||||
- `options.shared_memory` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore.
|
- `options.shared_memory` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore.
|
||||||
This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
|
This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
|
||||||
@@ -63,7 +63,7 @@ Returns the fastest route between two or more coordinates while visiting the way
|
|||||||
- `options.geometries` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
|
- `options.geometries` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`)
|
||||||
- `options.overview` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
|
- `options.overview` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`)
|
||||||
- `options.continue_straight` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile.
|
- `options.continue_straight` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile.
|
||||||
- `options.approaches` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
|
- `options.approaches` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Restrict the direction on the road network at a waypoint, relative to the input coordinate. Can be `null` (unrestricted, default), `curb` or `opposite`.
|
||||||
`null`/`true`/`false`
|
`null`/`true`/`false`
|
||||||
- `options.waypoints` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Indices to coordinates to treat as waypoints. If not supplied, all coordinates are waypoints. Must include first and last coordinate index.
|
- `options.waypoints` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Indices to coordinates to treat as waypoints. If not supplied, all coordinates are waypoints. Must include first and last coordinate index.
|
||||||
- `options.format` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which output format to use, either `json`, or [`flatbuffers`](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api/flatbuffers).
|
- `options.format` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which output format to use, either `json`, or [`flatbuffers`](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api/flatbuffers).
|
||||||
@@ -101,7 +101,7 @@ Note: `coordinates` in the general options only supports a single `{longitude},{
|
|||||||
- `options.generate_hints` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether or not adds a Hint to the response which can be used in subsequent requests. (optional, default `true`)
|
- `options.generate_hints` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Whether or not adds a Hint to the response which can be used in subsequent requests. (optional, default `true`)
|
||||||
- `options.number` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of nearest segments that should be returned.
|
- `options.number` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Number of nearest segments that should be returned.
|
||||||
Must be an integer greater than or equal to `1`. (optional, default `1`)
|
Must be an integer greater than or equal to `1`. (optional, default `1`)
|
||||||
- `options.approaches` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
|
- `options.approaches` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Restrict the direction on the road network at a waypoint, relative to the input coordinate. Can be `null` (unrestricted, default), `curb` or `opposite`.
|
||||||
- `options.format` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which output format to use, either `json`, or [`flatbuffers`](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api/flatbuffers).
|
- `options.format` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which output format to use, either `json`, or [`flatbuffers`](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api/flatbuffers).
|
||||||
- `options.snapping` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which edges can be snapped to, either `default`, or `any`. `default` only snaps to edges marked by the profile as `is_startpoint`, `any` will allow snapping to any edge in the routing graph.
|
- `options.snapping` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which edges can be snapped to, either `default`, or `any`. `default` only snaps to edges marked by the profile as `is_startpoint`, `any` will allow snapping to any edge in the routing graph.
|
||||||
- `callback` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)**
|
- `callback` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)**
|
||||||
@@ -141,7 +141,7 @@ Optionally returns distance table.
|
|||||||
- `options.sources` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** An array of `index` elements (`0 <= integer < #coordinates`) to use
|
- `options.sources` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** An array of `index` elements (`0 <= integer < #coordinates`) to use
|
||||||
location with given index as source. Default is to use all.
|
location with given index as source. Default is to use all.
|
||||||
- `options.destinations` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** An array of `index` elements (`0 <= integer < #coordinates`) to use location with given index as destination. Default is to use all.
|
- `options.destinations` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** An array of `index` elements (`0 <= integer < #coordinates`) to use location with given index as destination. Default is to use all.
|
||||||
- `options.approaches` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
|
- `options.approaches` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Restrict the direction on the road network at a waypoint, relative to the input coordinate.. Can be `null` (unrestricted, default), `curb` or `opposite`.
|
||||||
- `options.fallback_speed` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Replace `null` responses in result with as-the-crow-flies estimates based on `fallback_speed`. Value is in metres/second.
|
- `options.fallback_speed` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Replace `null` responses in result with as-the-crow-flies estimates based on `fallback_speed`. Value is in metres/second.
|
||||||
- `options.fallback_coordinate` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Either `input` (default) or `snapped`. If using a `fallback_speed`, use either the user-supplied coordinate (`input`), or the snapped coordinate (`snapped`) for calculating the as-the-crow-flies distance between two points.
|
- `options.fallback_coordinate` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Either `input` (default) or `snapped`. If using a `fallback_speed`, use either the user-supplied coordinate (`input`), or the snapped coordinate (`snapped`) for calculating the as-the-crow-flies distance between two points.
|
||||||
- `options.scale_factor` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Multiply the table duration values in the table by this number for more controlled input into a route optimization solver.
|
- `options.scale_factor` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Multiply the table duration values in the table by this number for more controlled input into a route optimization solver.
|
||||||
@@ -298,7 +298,7 @@ Right now, the following combinations are possible:
|
|||||||
- `options.roundtrip` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route is a roundtrip. (optional, default `true`)
|
- `options.roundtrip` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route is a roundtrip. (optional, default `true`)
|
||||||
- `options.source` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route starts at `any` or `first` coordinate. (optional, default `any`)
|
- `options.source` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route starts at `any` or `first` coordinate. (optional, default `any`)
|
||||||
- `options.destination` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route ends at `any` or `last` coordinate. (optional, default `any`)
|
- `options.destination` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Return route ends at `any` or `last` coordinate. (optional, default `any`)
|
||||||
- `options.approaches` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`.
|
- `options.approaches` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Restrict the direction on the road network at a waypoint, relative to the input coordinate. Can be `null` (unrestricted, default), `curb` or `opposite`.
|
||||||
- `options.snapping` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which edges can be snapped to, either `default`, or `any`. `default` only snaps to edges marked by the profile as `is_startpoint`, `any` will allow snapping to any edge in the routing graph.
|
- `options.snapping` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** Which edges can be snapped to, either `default`, or `any`. `default` only snaps to edges marked by the profile as `is_startpoint`, `any` will allow snapping to any edge in the routing graph.
|
||||||
- `callback` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)**
|
- `callback` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)**
|
||||||
|
|
||||||
|
|||||||
+7
-7
@@ -57,15 +57,15 @@ int main(int argc, const char *argv[])
|
|||||||
// Execute routing request, this does the heavy lifting
|
// Execute routing request, this does the heavy lifting
|
||||||
const auto status = osrm.Route(params, result);
|
const auto status = osrm.Route(params, result);
|
||||||
|
|
||||||
auto &json_result = result.get<json::Object>();
|
auto &json_result = std::get<json::Object>(result);
|
||||||
if (status == Status::Ok)
|
if (status == Status::Ok)
|
||||||
{
|
{
|
||||||
auto &routes = json_result.values["routes"].get<json::Array>();
|
auto &routes = std::get<json::Array>(json_result.values["routes"]);
|
||||||
|
|
||||||
// Let's just use the first route
|
// Let's just use the first route
|
||||||
auto &route = routes.values.at(0).get<json::Object>();
|
auto &route = std::get<json::Object>(routes.values.at(0));
|
||||||
const auto distance = route.values["distance"].get<json::Number>().value;
|
const auto distance = std::get<json::Number>(route.values["distance"]).value;
|
||||||
const auto duration = route.values["duration"].get<json::Number>().value;
|
const auto duration = std::get<json::Number>(route.values["duration"]).value;
|
||||||
|
|
||||||
// Warn users if extract does not contain the default coordinates from above
|
// Warn users if extract does not contain the default coordinates from above
|
||||||
if (distance == 0 || duration == 0)
|
if (distance == 0 || duration == 0)
|
||||||
@@ -80,8 +80,8 @@ int main(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
else if (status == Status::Error)
|
else if (status == Status::Error)
|
||||||
{
|
{
|
||||||
const auto code = json_result.values["code"].get<json::String>().value;
|
const auto code = std::get<json::String>(json_result.values["code"]).value;
|
||||||
const auto message = json_result.values["message"].get<json::String>().value;
|
const auto message = std::get<json::String>(json_result.values["message"]).value;
|
||||||
|
|
||||||
std::cout << "Code: " << code << "\n";
|
std::cout << "Code: " << code << "\n";
|
||||||
std::cout << "Message: " << code << "\n";
|
std::cout << "Message: " << code << "\n";
|
||||||
|
|||||||
@@ -32,14 +32,14 @@ Feature: Car - Handle traffic lights
|
|||||||
| l | traffic_signals |
|
| l | traffic_signals |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | time | # |
|
| from | to | time | # |
|
||||||
| 1 | 2 | 11.1s | no turn with no traffic light |
|
| 1 | 2 | 11.1s | no turn with no traffic light |
|
||||||
| 3 | 4 | 13.1s | no turn with traffic light |
|
| 3 | 4 | 13.1s | no turn with traffic light |
|
||||||
| g | j | 18.7s | turn with no traffic light |
|
| g | j | 18.7s | turn with no traffic light |
|
||||||
| k | n | 20.7s | turn with traffic light |
|
| k | n | 20.7s | turn with traffic light |
|
||||||
|
|
||||||
|
|
||||||
Scenario: Car - Traffic signal direction
|
Scenario: Car - Traffic signal direction straight
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
a-1-b-2-c
|
a-1-b-2-c
|
||||||
@@ -112,14 +112,14 @@ Feature: Car - Handle traffic lights
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Scenario: Car - Encounters a traffic light
|
Scenario: Car - Encounters a traffic light direction
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
a f k
|
a f k p
|
||||||
| | |
|
| | | |
|
||||||
b-c-d h-g-i l-m-n
|
b-c-d h-g-i l-m-n q-r-s
|
||||||
| | |
|
| | | |
|
||||||
e j o
|
e j o t
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -131,53 +131,70 @@ Feature: Car - Handle traffic lights
|
|||||||
| fgj | primary |
|
| fgj | primary |
|
||||||
| lmn | primary |
|
| lmn | primary |
|
||||||
| kmo | primary |
|
| kmo | primary |
|
||||||
|
| qrs | primary |
|
||||||
|
| prt | primary |
|
||||||
|
|
||||||
And the nodes
|
And the nodes
|
||||||
| node | highway | traffic_signals:direction |
|
| node | highway | traffic_signals:direction |
|
||||||
| g | traffic_signals | forward |
|
| g | traffic_signals | |
|
||||||
| m | traffic_signals | backward |
|
| m | traffic_signals | forward |
|
||||||
|
| r | traffic_signals | backward |
|
||||||
|
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
|
# Base case
|
||||||
| from | to | time | # |
|
| from | to | time | # |
|
||||||
| a | d | 21.9s | no turn with no traffic light |
|
|
||||||
| a | e | 22.2s | no turn with traffic light |
|
|
||||||
| a | b | 18.7s | turn with no traffic light |
|
| a | b | 18.7s | turn with no traffic light |
|
||||||
| e | b | 21.9s | no turn with no traffic light |
|
| a | e | 22.2s | no turn with no traffic light |
|
||||||
| e | a | 22.2s | no turn with traffic light |
|
| a | d | 21.9s | turn with no traffic light |
|
||||||
|
| e | b | 21.9s | turn with no traffic light |
|
||||||
|
| e | a | 22.2s | no turn with no traffic light |
|
||||||
| e | d | 18.7s | turn with no traffic light |
|
| e | d | 18.7s | turn with no traffic light |
|
||||||
| d | e | 21.9s | no turn with no traffic light |
|
| d | e | 21.9s | turn with no traffic light |
|
||||||
| d | b | 11s | no turn with traffic light |
|
| d | b | 11s | no turn with no traffic light |
|
||||||
| d | a | 18.7s | turn with no traffic light |
|
| d | a | 18.7s | turn with no traffic light |
|
||||||
| b | a | 21.9s | no turn with no traffic light |
|
| b | a | 21.9s | turn with no traffic light |
|
||||||
| b | d | 11s | no turn with traffic light |
|
| b | d | 11s | no turn with no traffic light |
|
||||||
| b | e | 18.7s | turn with no traffic light |
|
| b | e | 18.7s | turn with no traffic light |
|
||||||
|
# All have traffic lights - 2s penalty
|
||||||
| f | i | 23.9s | no turn with no traffic light |
|
| f | h | 20.7s | turn with traffic light |
|
||||||
| f | j | 24.2s | no turn with traffic light |
|
| f | j | 24.2s | no turn with traffic light |
|
||||||
| f | h | 20.7s | turn with no traffic light |
|
| f | i | 23.9s | turn with traffic light |
|
||||||
| j | h | 21.9s | no turn with no traffic light |
|
| j | h | 23.9s | turn with traffic light |
|
||||||
| j | f | 22.2s | no turn with traffic light |
|
| j | f | 24.2s | no turn with traffic light |
|
||||||
| j | i | 18.7s | turn with no traffic light |
|
| j | i | 20.7s | turn with traffic light |
|
||||||
| i | j | 21.9s | no turn with no traffic light |
|
| i | j | 23.9s | turn with traffic light |
|
||||||
| i | h | 11s | no turn with traffic light |
|
| i | h | 13s | no turn with traffic light |
|
||||||
| i | f | 18.7s | turn with no traffic light |
|
| i | f | 20.7s | turn with traffic light |
|
||||||
| h | f | 23.9s | no turn with no traffic light |
|
| h | f | 23.9s | turn with traffic light |
|
||||||
| h | i | 13s | no turn with traffic light |
|
| h | i | 13s | no turn with traffic light |
|
||||||
| h | j | 20.7s | turn with no traffic light |
|
| h | j | 20.7s | turn with traffic light |
|
||||||
|
# Front direction have traffic lights - 2s penalty
|
||||||
| k | n | 21.9s | no turn with no traffic light |
|
| k | l | 20.7s | turn with traffic light |
|
||||||
| k | o | 22.2s | no turn with traffic light |
|
| k | o | 24.2s | no turn with traffic light |
|
||||||
| k | l | 18.7s | turn with no traffic light |
|
| k | n | 23.9s | turn with traffic light |
|
||||||
| o | l | 23.9s | no turn with no traffic light |
|
| o | l | 21.9s | turn with no traffic light |
|
||||||
| o | k | 24.2s | no turn with traffic light |
|
| o | k | 22.2s | no turn with no traffic light |
|
||||||
| o | n | 20.7s | turn with no traffic light |
|
| o | n | 18.7s | turn with no traffic light |
|
||||||
| n | o | 23.9s | no turn with no traffic light |
|
| n | o | 21.9s | turn with no traffic light |
|
||||||
| n | l | 13s | no turn with traffic light |
|
| n | l | 11s | no turn with no traffic light |
|
||||||
| n | k | 20.7s | turn with no traffic light |
|
| n | k | 18.7s | turn with no traffic light |
|
||||||
| l | k | 21.9s | no turn with no traffic light |
|
| l | k | 23.9s | turn with traffic light |
|
||||||
| l | n | 11s | no turn with traffic light |
|
| l | n | 13s | no turn with traffic light |
|
||||||
| l | o | 18.7s | turn with no traffic light |
|
| l | o | 20.7s | turn with traffic light |
|
||||||
|
# Reverse direction have traffic lights - 2s penalty
|
||||||
|
| p | q | 18.7s | turn with no traffic light |
|
||||||
|
| p | t | 22.2s | no turn with no traffic light |
|
||||||
|
| p | s | 21.9s | turn with no traffic light |
|
||||||
|
| t | q | 23.9s | turn with traffic light |
|
||||||
|
| t | p | 24.2s | no turn with traffic light |
|
||||||
|
| t | s | 20.7s | turn with traffic light |
|
||||||
|
| s | t | 23.9s | turn with traffic light |
|
||||||
|
| s | q | 13s | no turn with traffic light |
|
||||||
|
| s | p | 20.7s | turn with traffic light |
|
||||||
|
| q | p | 21.9s | turn with no traffic light |
|
||||||
|
| q | s | 11s | no turn with no traffic light |
|
||||||
|
| q | t | 18.7s | turn with no traffic light |
|
||||||
|
|
||||||
|
|
||||||
Scenario: Traffic Signal Geometry
|
Scenario: Traffic Signal Geometry
|
||||||
@@ -343,3 +360,106 @@ Feature: Car - Handle traffic lights
|
|||||||
| from | to | route | speed | weights | time | distances | a:datasources | a:nodes | a:speed | a:duration | a:weight |
|
| from | to | route | speed | weights | time | distances | a:datasources | a:nodes | a:speed | a:duration | a:weight |
|
||||||
| a | c | abc,abc | 65 km/h | 22.2,0 | 22.2s | 400m,0m | 1:0 | 1:2:3 | 18:18 | 11.1:11.1 | 11.1:11.1 |
|
| a | c | abc,abc | 65 km/h | 22.2,0 | 22.2s | 400m,0m | 1:0 | 1:2:3 | 18:18 | 11.1:11.1 | 11.1:11.1 |
|
||||||
| c | a | abc,abc | 60 km/h | 24.2,0 | 24.2s | 400m,0m | 0:1 | 3:2:1 | 18:18 | 11.1:11.1 | 11.1:11.1 |
|
| c | a | abc,abc | 60 km/h | 24.2,0 | 24.2s | 400m,0m | 0:1 | 3:2:1 | 18:18 | 11.1:11.1 | 11.1:11.1 |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Car - Traffic signal straight direction with edge compression
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
a-1-b - c - d-2-e
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abcde | primary |
|
||||||
|
|
||||||
|
And the nodes
|
||||||
|
| node | highway | traffic_signals:direction |
|
||||||
|
| c | traffic_signals | forward |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | time | weight | # |
|
||||||
|
| 1 | 2 | 35.3s | 35.3 | no turn with traffic light |
|
||||||
|
| 2 | 1 | 33.3s | 33.3 | no turn with no traffic light |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Car - Traffic signal turn direction with edge compression
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
d
|
||||||
|
|
|
||||||
|
2
|
||||||
|
|
|
||||||
|
a-1-b - c - f
|
||||||
|
|
|
||||||
|
e
|
||||||
|
|
||||||
|
j
|
||||||
|
|
|
||||||
|
4
|
||||||
|
|
|
||||||
|
g-3-h - i - k
|
||||||
|
|
|
||||||
|
l
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| cf | primary |
|
||||||
|
| fd | primary |
|
||||||
|
| fe | primary |
|
||||||
|
| ghi | primary |
|
||||||
|
| ik | primary |
|
||||||
|
| kj | primary |
|
||||||
|
| kl | primary |
|
||||||
|
|
||||||
|
And the nodes
|
||||||
|
| node | highway | traffic_signals:direction |
|
||||||
|
| k | traffic_signals | forward |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | time | weight | # |
|
||||||
|
| 1 | 2 | 44.2s | 44.2 | turn with no traffic light |
|
||||||
|
| 2 | 1 | 41s | 41 | turn with no traffic light |
|
||||||
|
| 3 | 4 | 46.2s | 46.2 | turn with traffic light |
|
||||||
|
| 4 | 3 | 41s | 41 | turn with no traffic light |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Car - Traffic signal turn direction with turn restriction
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
d
|
||||||
|
|
|
||||||
|
2
|
||||||
|
|
|
||||||
|
a-1-b - c - f
|
||||||
|
|
|
||||||
|
e
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | highway |
|
||||||
|
| abc | primary |
|
||||||
|
| cf | primary |
|
||||||
|
| fd | primary |
|
||||||
|
| fe | primary |
|
||||||
|
|
||||||
|
And the nodes
|
||||||
|
| node | highway | traffic_signals:direction |
|
||||||
|
| f | traffic_signals | forward |
|
||||||
|
|
||||||
|
And the relations
|
||||||
|
| type | way:from | way:to | way:via | restriction |
|
||||||
|
| restriction | abc | fe | cf | no_right_turn |
|
||||||
|
|
||||||
|
And the relations
|
||||||
|
| type | way:from | way:to | node:via | restriction |
|
||||||
|
| restriction | df | fc | f | right_turn_only |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | time | weight | # |
|
||||||
|
| 1 | 2 | 46.2s | 46.2 | turn with traffic light |
|
||||||
|
| 2 | 1 | 41s | 41 | turn with no traffic light |
|
||||||
|
|||||||
@@ -188,16 +188,11 @@ class OSRMLoader {
|
|||||||
this.loader = {shutdown: (cb) => cb() };
|
this.loader = {shutdown: (cb) => cb() };
|
||||||
}
|
}
|
||||||
if (this.method === 'datastore') {
|
if (this.method === 'datastore') {
|
||||||
// shutdown only if we are switching from another loader type
|
this.loader.shutdown((err) => {
|
||||||
if (this.loader !== this.sharedLoader) {
|
if (err) return callback(err);
|
||||||
this.loader.shutdown((err) => {
|
this.loader = this.sharedLoader;
|
||||||
if (err) return callback(err);
|
this.sharedLoader.load(inputFile, callback);
|
||||||
this.loader = this.sharedLoader;
|
});
|
||||||
this.sharedLoader.load(inputFile, callback);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.sharedLoader.load(inputFile, callback);
|
|
||||||
}
|
|
||||||
} else if (this.method === 'directly') {
|
} else if (this.method === 'directly') {
|
||||||
this.loader.shutdown((err) => {
|
this.loader.shutdown((err) => {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
@@ -206,12 +201,12 @@ class OSRMLoader {
|
|||||||
});
|
});
|
||||||
} else if (this.method === 'mmap') {
|
} else if (this.method === 'mmap') {
|
||||||
this.loader.shutdown((err) => {
|
this.loader.shutdown((err) => {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
this.loader = this.mmapLoader;
|
this.loader = this.mmapLoader;
|
||||||
this.mmapLoader.load(inputFile, callback);
|
this.mmapLoader.load(inputFile, callback);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
callback(new Error('*** Unknown load method ' + this.method));
|
callback(new Error('*** Unknown load method ' + method));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,3 +154,27 @@ Feature: osrm-extract lua ways:get_nodes()
|
|||||||
Then it should exit successfully
|
Then it should exit successfully
|
||||||
And stdout should contain "node 42"
|
And stdout should contain "node 42"
|
||||||
And stdout should contain "way 42"
|
And stdout should contain "way 42"
|
||||||
|
|
||||||
|
Scenario: osrm-extract flags accessible in process_segment function
|
||||||
|
Given the profile file
|
||||||
|
"""
|
||||||
|
functions = require('testbot')
|
||||||
|
|
||||||
|
functions.process_segment = function (profile, segment)
|
||||||
|
print('segment forward ' .. tostring(segment.flags.forward) .. ' backward ' .. tostring(segment.flags.backward))
|
||||||
|
end
|
||||||
|
|
||||||
|
return functions
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
a b
|
||||||
|
"""
|
||||||
|
And the ways
|
||||||
|
| nodes | oneway |
|
||||||
|
| ab | yes |
|
||||||
|
And the data has been saved to disk
|
||||||
|
When I run "osrm-extract --profile {profile_file} {osm_file}"
|
||||||
|
Then it should exit successfully
|
||||||
|
And stdout should contain "segment forward true backward false"
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ Feature: osrm-routed command line options: help
|
|||||||
Background:
|
Background:
|
||||||
Given the profile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: osrm-routed - Help should be shown when no options are passed
|
Scenario: osrm-routed - Help should be shown when no options are passed
|
||||||
When I run "osrm-routed"
|
When I run "osrm-routed"
|
||||||
Then stderr should be empty
|
Then stderr should be empty
|
||||||
@@ -24,9 +23,9 @@ Feature: osrm-routed command line options: help
|
|||||||
And stdout should contain "--max-table-size"
|
And stdout should contain "--max-table-size"
|
||||||
And stdout should contain "--max-matching-size"
|
And stdout should contain "--max-matching-size"
|
||||||
And stdout should contain "--default-radius"
|
And stdout should contain "--default-radius"
|
||||||
|
And stdout should contain "--keepalive-timeout"
|
||||||
And it should exit successfully
|
And it should exit successfully
|
||||||
|
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: osrm-routed - Help, short
|
Scenario: osrm-routed - Help, short
|
||||||
When I run "osrm-routed -h"
|
When I run "osrm-routed -h"
|
||||||
Then stderr should be empty
|
Then stderr should be empty
|
||||||
@@ -46,10 +45,9 @@ Feature: osrm-routed command line options: help
|
|||||||
And stdout should contain "--max-table-size"
|
And stdout should contain "--max-table-size"
|
||||||
And stdout should contain "--max-matching-size"
|
And stdout should contain "--max-matching-size"
|
||||||
And stdout should contain "--default-radius"
|
And stdout should contain "--default-radius"
|
||||||
|
And stdout should contain "--keepalive-timeout"
|
||||||
And it should exit successfully
|
And it should exit successfully
|
||||||
|
|
||||||
|
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: osrm-routed - Help, long
|
Scenario: osrm-routed - Help, long
|
||||||
When I run "osrm-routed --help"
|
When I run "osrm-routed --help"
|
||||||
Then stderr should be empty
|
Then stderr should be empty
|
||||||
@@ -69,4 +67,5 @@ Feature: osrm-routed command line options: help
|
|||||||
And stdout should contain "--max-table-size"
|
And stdout should contain "--max-table-size"
|
||||||
And stdout should contain "--max-matching-size"
|
And stdout should contain "--max-matching-size"
|
||||||
And stdout should contain "--default-radius"
|
And stdout should contain "--default-radius"
|
||||||
|
And stdout should contain "--keepalive-timeout"
|
||||||
And it should exit successfully
|
And it should exit successfully
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ Feature: osrm-routed command line options: invalid options
|
|||||||
Background:
|
Background:
|
||||||
Given the profile "testbot"
|
Given the profile "testbot"
|
||||||
|
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: osrm-routed - Non-existing option
|
Scenario: osrm-routed - Non-existing option
|
||||||
When I try to run "osrm-routed --fly-me-to-the-moon"
|
When I try to run "osrm-routed --fly-me-to-the-moon"
|
||||||
Then stdout should be empty
|
Then stdout should be empty
|
||||||
@@ -12,7 +11,6 @@ Feature: osrm-routed command line options: invalid options
|
|||||||
And stderr should contain "fly-me-to-the-moon"
|
And stderr should contain "fly-me-to-the-moon"
|
||||||
And it should exit with an error
|
And it should exit with an error
|
||||||
|
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: osrm-routed - Missing file
|
Scenario: osrm-routed - Missing file
|
||||||
When I try to run "osrm-routed over-the-rainbow.osrm"
|
When I try to run "osrm-routed over-the-rainbow.osrm"
|
||||||
Then stderr should contain "over-the-rainbow.osrm"
|
Then stderr should contain "over-the-rainbow.osrm"
|
||||||
|
|||||||
@@ -33,11 +33,6 @@ module.exports = function () {
|
|||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.Then(/^HTTP code should be (\d+)$/, (code, callback) => {
|
|
||||||
assert(this.response.statusCode, parseInt(code));
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.Then(/^status message should be "(.*?)"$/, (message, callback) => {
|
this.Then(/^status message should be "(.*?)"$/, (message, callback) => {
|
||||||
try {
|
try {
|
||||||
this.json = JSON.parse(this.response.body);
|
this.json = JSON.parse(this.response.body);
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ module.exports = function () {
|
|||||||
this.setDefaultTimeout(this.TIMEOUT);
|
this.setDefaultTimeout(this.TIMEOUT);
|
||||||
this.ROOT_PATH = process.cwd();
|
this.ROOT_PATH = process.cwd();
|
||||||
|
|
||||||
this.USE_ROUTED_JS = process.env.OSRM_USE_ROUTED_JS || false;
|
|
||||||
|
|
||||||
this.TEST_PATH = path.resolve(this.ROOT_PATH, 'test');
|
this.TEST_PATH = path.resolve(this.ROOT_PATH, 'test');
|
||||||
this.CACHE_PATH = path.resolve(this.TEST_PATH, 'cache');
|
this.CACHE_PATH = path.resolve(this.TEST_PATH, 'cache');
|
||||||
this.LOGS_PATH = path.resolve(this.TEST_PATH, 'logs');
|
this.LOGS_PATH = path.resolve(this.TEST_PATH, 'logs');
|
||||||
@@ -43,8 +41,8 @@ module.exports = function () {
|
|||||||
|
|
||||||
this.OSRM_PORT = process.env.OSRM_PORT && parseInt(process.env.OSRM_PORT) || 5000;
|
this.OSRM_PORT = process.env.OSRM_PORT && parseInt(process.env.OSRM_PORT) || 5000;
|
||||||
this.OSRM_IP = process.env.OSRM_IP || '127.0.0.1';
|
this.OSRM_IP = process.env.OSRM_IP || '127.0.0.1';
|
||||||
this.OSRM_CONNECTION_RETRIES = process.env.OSRM_CONNECTION_RETRIES && parseInt(process.env.OSRM_CONNECTION_RETRIES) || 100;
|
this.OSRM_CONNECTION_RETRIES = process.env.OSRM_CONNECTION_RETRIES && parseInt(process.env.OSRM_CONNECTION_RETRIES) || 10;
|
||||||
this.OSRM_CONNECTION_EXP_BACKOFF_COEF = process.env.OSRM_CONNECTION_EXP_BACKOFF_COEF && parseFloat(process.env.OSRM_CONNECTION_EXP_BACKOFF_COEF) || 1.0;
|
this.OSRM_CONNECTION_EXP_BACKOFF_COEF = process.env.OSRM_CONNECTION_EXP_BACKOFF_COEF && parseFloat(process.env.OSRM_CONNECTION_EXP_BACKOFF_COEF) || 1.1;
|
||||||
|
|
||||||
this.HOST = `http://${this.OSRM_IP}:${this.OSRM_PORT}`;
|
this.HOST = `http://${this.OSRM_IP}:${this.OSRM_PORT}`;
|
||||||
|
|
||||||
|
|||||||
@@ -39,11 +39,7 @@ module.exports = function () {
|
|||||||
|
|
||||||
this.runBin = (bin, options, env, callback) => {
|
this.runBin = (bin, options, env, callback) => {
|
||||||
let cmd = path.resolve(util.format('%s/%s%s', this.BIN_PATH, bin, this.EXE));
|
let cmd = path.resolve(util.format('%s/%s%s', this.BIN_PATH, bin, this.EXE));
|
||||||
if (this.USE_ROUTED_JS && bin === 'osrm-routed') {
|
|
||||||
cmd = 'osrm-routed-js';
|
|
||||||
}
|
|
||||||
let opts = options.split(' ').filter((x) => { return x && x.length > 0; });
|
let opts = options.split(' ').filter((x) => { return x && x.length > 0; });
|
||||||
|
|
||||||
let log = fs.createWriteStream(this.scenarioLogFile, {'flags': 'a'});
|
let log = fs.createWriteStream(this.scenarioLogFile, {'flags': 'a'});
|
||||||
log.write(util.format('*** running %s %s\n', cmd, options));
|
log.write(util.format('*** running %s %s\n', cmd, options));
|
||||||
// we need to set a large maxbuffer here because we have long running processes like osrm-routed
|
// we need to set a large maxbuffer here because we have long running processes like osrm-routed
|
||||||
|
|||||||
@@ -115,4 +115,4 @@ Feature: Annotations
|
|||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | route | a:speed | a:distance | a:duration | a:nodes |
|
| from | to | route | a:speed | a:distance | a:duration | a:nodes |
|
||||||
| a | c | abc,abc | 10:10 | 249.9876189:299.962882 +- 1e-7 | 25:30 | 1:2:3 |
|
| a | c | abc,abc | 10:10 | 249.9876189:299.962882 | 25:30 | 1:2:3 |
|
||||||
|
|||||||
@@ -38,7 +38,41 @@ Feature: Approach parameter
|
|||||||
| from | to | approaches | route |
|
| from | to | approaches | route |
|
||||||
| s | e | unrestricted curb | ab,bc,bc |
|
| s | e | unrestricted curb | ab,bc,bc |
|
||||||
|
|
||||||
Scenario: Start End opposite approach, option unrestricted for Start and End
|
Scenario: Start End same approach, option unrestricted for Start and opposite for End
|
||||||
|
Given the profile "testbot"
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
s e
|
||||||
|
a------b------c
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | unrestricted opposite | ab,bc |
|
||||||
|
|
||||||
|
Scenario: Start End same approach, option opposite for Start and curb for End
|
||||||
|
Given the profile "testbot"
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
s e
|
||||||
|
a------b------c
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | opposite curb | ab,bc,bc |
|
||||||
|
|
||||||
|
Scenario: Start End different approach, option unrestricted for Start and End
|
||||||
Given the profile "testbot"
|
Given the profile "testbot"
|
||||||
And the node map
|
And the node map
|
||||||
"""
|
"""
|
||||||
@@ -56,7 +90,7 @@ Feature: Approach parameter
|
|||||||
| from | to | approaches | route |
|
| from | to | approaches | route |
|
||||||
| s | e | unrestricted unrestricted | ab,bc |
|
| s | e | unrestricted unrestricted | ab,bc |
|
||||||
|
|
||||||
Scenario: Start End opposite approach, option unrestricted for Start and curb for End
|
Scenario: Start End different approach, option unrestricted for Start and curb for End
|
||||||
Given the profile "testbot"
|
Given the profile "testbot"
|
||||||
And the node map
|
And the node map
|
||||||
"""
|
"""
|
||||||
@@ -74,6 +108,43 @@ Feature: Approach parameter
|
|||||||
| from | to | approaches | route |
|
| from | to | approaches | route |
|
||||||
| s | e | unrestricted curb | ab,bc |
|
| s | e | unrestricted curb | ab,bc |
|
||||||
|
|
||||||
|
Scenario: Start End different approach, option unrestricted for Start and opposite for End
|
||||||
|
Given the profile "testbot"
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
s
|
||||||
|
a------b------c
|
||||||
|
e
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | unrestricted opposite | ab,bc,bc |
|
||||||
|
|
||||||
|
Scenario: Start End different approach, option curb for Start and opposite for End
|
||||||
|
Given the profile "testbot"
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
e
|
||||||
|
a------b------c-----------d
|
||||||
|
s
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
| cd |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | curb opposite | cd,cd,ab,ab |
|
||||||
|
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# Oneway Test #
|
# Oneway Test #
|
||||||
@@ -111,10 +182,44 @@ Feature: Approach parameter
|
|||||||
| bc | yes |
|
| bc | yes |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | approaches | route |
|
| from | to | approaches | route |
|
||||||
| s | e | unrestricted curb | ab,bc |
|
| s | e | unrestricted curb | ab,bc |
|
||||||
|
|
||||||
Scenario: Test on oneway segment, Start End opposite approach, option unrestricted for Start and End
|
Scenario: Test on oneway segment, Start End same approach, option unrestricted for Start and opposite for End
|
||||||
|
Given the profile "testbot"
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
s e
|
||||||
|
a------b------c
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | oneway |
|
||||||
|
| ab | yes |
|
||||||
|
| bc | yes |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | unrestricted opposite | ab,bc |
|
||||||
|
|
||||||
|
Scenario: Test on oneway segment, Start End same approach, option opposite for Start and curb for End
|
||||||
|
Given the profile "testbot"
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
s e
|
||||||
|
a------b------c
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | oneway |
|
||||||
|
| ab | yes |
|
||||||
|
| bc | yes |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | opposite curb | ab,bc |
|
||||||
|
|
||||||
|
Scenario: Test on oneway segment, Start End different approach, option unrestricted for Start and End
|
||||||
Given the profile "testbot"
|
Given the profile "testbot"
|
||||||
And the node map
|
And the node map
|
||||||
"""
|
"""
|
||||||
@@ -132,7 +237,7 @@ Feature: Approach parameter
|
|||||||
| from | to | approaches | route |
|
| from | to | approaches | route |
|
||||||
| s | e | unrestricted unrestricted | ab,bc |
|
| s | e | unrestricted unrestricted | ab,bc |
|
||||||
|
|
||||||
Scenario: Test on oneway segment, Start End opposite approach, option unrestricted for Start and curb for End
|
Scenario: Test on oneway segment, Start End different approach, option unrestricted for Start and curb for End
|
||||||
Given the profile "testbot"
|
Given the profile "testbot"
|
||||||
And the node map
|
And the node map
|
||||||
"""
|
"""
|
||||||
@@ -150,6 +255,42 @@ Feature: Approach parameter
|
|||||||
| from | to | approaches | route |
|
| from | to | approaches | route |
|
||||||
| s | e | unrestricted curb | ab,bc |
|
| s | e | unrestricted curb | ab,bc |
|
||||||
|
|
||||||
|
Scenario: Test on oneway segment, Start End different approach, option unrestricted for Start and opposite for End
|
||||||
|
Given the profile "testbot"
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
s
|
||||||
|
a------b------c
|
||||||
|
e
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | oneway |
|
||||||
|
| ab | yes |
|
||||||
|
| bc | yes |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | unrestricted opposite | ab,bc |
|
||||||
|
|
||||||
|
Scenario: Test on oneway segment, Start End different approach, option curb for Start and opposite for End
|
||||||
|
Given the profile "testbot"
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
s
|
||||||
|
a------b------c
|
||||||
|
e
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | oneway |
|
||||||
|
| ab | yes |
|
||||||
|
| bc | yes |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | curb opposite | ab,bc |
|
||||||
|
|
||||||
##############
|
##############
|
||||||
# UTurn Test #
|
# UTurn Test #
|
||||||
##############
|
##############
|
||||||
@@ -175,6 +316,27 @@ Feature: Approach parameter
|
|||||||
| from | to | approaches | route |
|
| from | to | approaches | route |
|
||||||
| s | e | unrestricted curb | |
|
| s | e | unrestricted curb | |
|
||||||
|
|
||||||
|
Scenario: UTurn test, router can find a route because uturn authorized to reach opposite side
|
||||||
|
Given the profile "testbot"
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
e s
|
||||||
|
a------b------c
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
|
||||||
|
And the relations
|
||||||
|
| type | way:from | way:to | node:via | restriction |
|
||||||
|
| restriction | bc | bc | c | no_u_turn |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | curb opposite | bc,ab,ab |
|
||||||
|
|
||||||
|
|
||||||
Scenario: UTurn test, router can find a route because he can use the roundabout
|
Scenario: UTurn test, router can find a route because he can use the roundabout
|
||||||
Given the profile "testbot"
|
Given the profile "testbot"
|
||||||
@@ -198,8 +360,9 @@ Feature: Approach parameter
|
|||||||
| restriction | bc | bc | c | no_u_turn |
|
| restriction | bc | bc | c | no_u_turn |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | approaches | route |
|
| from | to | approaches | route |
|
||||||
| s | e | unrestricted curb | ab,bc,bc |
|
| s | e | unrestricted curb | ab,bc,bc |
|
||||||
|
| s | e | opposite curb | ab,bc,bc |
|
||||||
|
|
||||||
|
|
||||||
Scenario: Start End same approach, option unrestricted for Start and curb for End, left-hand driving
|
Scenario: Start End same approach, option unrestricted for Start and curb for End, left-hand driving
|
||||||
@@ -228,6 +391,32 @@ Feature: Approach parameter
|
|||||||
| from | to | approaches | route |
|
| from | to | approaches | route |
|
||||||
| s | e | unrestricted curb | ab,bc |
|
| s | e | unrestricted curb | ab,bc |
|
||||||
|
|
||||||
|
Scenario: Start End same approach, option unrestricted for Start and opposite for End, left-hand driving
|
||||||
|
Given the profile file
|
||||||
|
"""
|
||||||
|
local functions = require('testbot')
|
||||||
|
local testbot_process_way = functions.process_way
|
||||||
|
functions.process_way = function(profile, way, result)
|
||||||
|
testbot_process_way(profile, way, result)
|
||||||
|
result.is_left_hand_driving = true
|
||||||
|
end
|
||||||
|
return functions
|
||||||
|
"""
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
s e
|
||||||
|
a------b------c
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | unrestricted opposite | ab,bc,bc |
|
||||||
|
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
# Left-side countries #
|
# Left-side countries #
|
||||||
@@ -260,9 +449,8 @@ Feature: Approach parameter
|
|||||||
"""
|
"""
|
||||||
And the node map
|
And the node map
|
||||||
"""
|
"""
|
||||||
s
|
s e
|
||||||
a------b------c
|
a------b------c
|
||||||
e
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
@@ -271,10 +459,50 @@ Feature: Approach parameter
|
|||||||
| bc |
|
| bc |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | approaches | route |
|
| from | to | approaches | route |
|
||||||
| s | e | unrestricted curb | ab,bc,bc |
|
| s | e | unrestricted curb | ab,bc |
|
||||||
|
|
||||||
Scenario: [Left-hand-side] Start End opposite approach, option unrestricted for Start and End
|
Scenario: [Left-hand-side] Start End same approach, option unrestricted for Start and opposite for End
|
||||||
|
Given the profile file "car" initialized with
|
||||||
|
"""
|
||||||
|
profile.properties.left_hand_driving = true
|
||||||
|
"""
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
s e
|
||||||
|
a------b------c
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | unrestricted opposite | ab,bc,bc |
|
||||||
|
|
||||||
|
Scenario: [Left-hand-side] Start End same approach, option opposite for Start and curb for End
|
||||||
|
Given the profile file "car" initialized with
|
||||||
|
"""
|
||||||
|
profile.properties.left_hand_driving = true
|
||||||
|
"""
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
e s
|
||||||
|
a------b------c
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | opposite curb | bc,ab,ab |
|
||||||
|
|
||||||
|
Scenario: [Left-hand-side] Start End different approach, option unrestricted for Start and End
|
||||||
Given the profile file "car" initialized with
|
Given the profile file "car" initialized with
|
||||||
"""
|
"""
|
||||||
profile.properties.left_hand_driving = true
|
profile.properties.left_hand_driving = true
|
||||||
@@ -295,15 +523,16 @@ Feature: Approach parameter
|
|||||||
| from | to | approaches | route |
|
| from | to | approaches | route |
|
||||||
| s | e | unrestricted unrestricted | ab,bc |
|
| s | e | unrestricted unrestricted | ab,bc |
|
||||||
|
|
||||||
Scenario: [Left-hand-side] Start End opposite approach, option unrestricted for Start and curb for End
|
Scenario: [Left-hand-side] Start End different approach, option unrestricted for Start and curb for End
|
||||||
Given the profile file "car" initialized with
|
Given the profile file "car" initialized with
|
||||||
"""
|
"""
|
||||||
profile.properties.left_hand_driving = true
|
profile.properties.left_hand_driving = true
|
||||||
"""
|
"""
|
||||||
And the node map
|
And the node map
|
||||||
"""
|
"""
|
||||||
s e
|
s
|
||||||
a------b------c
|
a------b------c
|
||||||
|
e
|
||||||
"""
|
"""
|
||||||
|
|
||||||
And the ways
|
And the ways
|
||||||
@@ -312,5 +541,122 @@ Feature: Approach parameter
|
|||||||
| bc |
|
| bc |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | approaches | route |
|
| from | to | approaches | route |
|
||||||
| s | e | unrestricted curb | ab,bc |
|
| s | e | unrestricted curb | ab,bc,bc |
|
||||||
|
|
||||||
|
Scenario: [Left-hand-side] Start End different approach, option unrestricted for Start and opposite for End
|
||||||
|
Given the profile file "car" initialized with
|
||||||
|
"""
|
||||||
|
profile.properties.left_hand_driving = true
|
||||||
|
"""
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
s
|
||||||
|
a------b------c
|
||||||
|
e
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | unrestricted opposite | ab,bc |
|
||||||
|
|
||||||
|
Scenario: [Left-hand-side] Start End different approach, option curb for Start and opposite for End
|
||||||
|
Given the profile file "car" initialized with
|
||||||
|
"""
|
||||||
|
profile.properties.left_hand_driving = true
|
||||||
|
"""
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
s
|
||||||
|
a------b------c
|
||||||
|
e
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| from | to | approaches | route |
|
||||||
|
| s | e | curb opposite | ab,bc |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Routes with more than two waypoints - uturns allowed
|
||||||
|
Given the profile "testbot"
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
2 1
|
||||||
|
a------b------c-----------d
|
||||||
|
|
|
||||||
|
3 | 4
|
||||||
|
e------f------g-----------h
|
||||||
|
|
|
||||||
|
|
|
||||||
|
i
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
| cd |
|
||||||
|
| bf |
|
||||||
|
| ef |
|
||||||
|
| fg |
|
||||||
|
| gh |
|
||||||
|
| ei |
|
||||||
|
|
||||||
|
And the query options
|
||||||
|
| continue_straight | false |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | approaches | locations | # |
|
||||||
|
| 1,2,3,4 | curb curb curb curb | _,_,_,a,b,f,_,_,i,h,_ | 1,2,2,a,b,f,3,3,i,h,4 (Only u-turn at end of roads) |
|
||||||
|
| 1,2,3,4 | curb unrestricted unrestricted curb | _,_,_,b,f,_,_,h,_ | 1,2,2,b,f,3,3,h,4 (Can u-turn at 2 and 3) |
|
||||||
|
| 1,2,3,4 | opposite opposite opposite opposite | _,d,a,_,_,b,f,i,_,_,_ | 1,d,a,2,2,b,f,i,3,3,4 (Only u-turn at end of roads) |
|
||||||
|
| 1,2,3,4 | opposite unrestricted unrestricted opposite | _,d,_,_,b,f,_,_,_ | 1,d,2,2,b,f,3,3,4 (Can u-turn at 2 and 3) |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: Routes with more than two waypoints - uturns forbidden
|
||||||
|
Given the profile "testbot"
|
||||||
|
And the node map
|
||||||
|
"""
|
||||||
|
2 1
|
||||||
|
a------b------c-----------d
|
||||||
|
|
|
||||||
|
3 | 4
|
||||||
|
e------f------g-----------h
|
||||||
|
|
|
||||||
|
|
|
||||||
|
i
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes |
|
||||||
|
| ab |
|
||||||
|
| bc |
|
||||||
|
| cd |
|
||||||
|
| bf |
|
||||||
|
| ef |
|
||||||
|
| fg |
|
||||||
|
| gh |
|
||||||
|
| ei |
|
||||||
|
|
||||||
|
And the query options
|
||||||
|
| continue_straight | true |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | approaches | locations | # |
|
||||||
|
| 1,2,3,4 | curb curb curb curb | _,_,_,a,b,f,_,_,i,h,_ | 1,2,2,a,b,f,3,3,i,h,4 (Only u-turn at end of roads) |
|
||||||
|
| 1,2,3,4 | curb opposite opposite curb | _,a,_,_,b,f,i,_,_,h,_ | 1,a,2,2,b,f,i,3,3,h,4 (switches stops with u-turns) |
|
||||||
|
| 1,2,3,4 | opposite opposite opposite opposite | _,d,a,_,_,b,f,i,_,_,_ | 1,d,a,2,2,b,f,i,3,3,4 (Only u-turn at end of roads) |
|
||||||
|
| 1,2,3,4 | opposite curb curb opposite | _,d,_,_,a,b,f,_,_,i,_ | 1,d,2,2,a,b,f,3,3,i,4 (switches stops with u-turns) |
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ Feature: Testbot - Exclude flags
|
|||||||
| a | c | |
|
| a | c | |
|
||||||
| a | f | |
|
| a | f | |
|
||||||
| f | d | fg,gd,gd |
|
| f | d | fg,gd,gd |
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: Testbot - exclude with unsupported exclude combination
|
Scenario: Testbot - exclude with unsupported exclude combination
|
||||||
Given the query options
|
Given the query options
|
||||||
| exclude | TwoWords2 |
|
| exclude | TwoWords2 |
|
||||||
@@ -88,7 +88,7 @@ Feature: Testbot - Exclude flags
|
|||||||
When I route I should get
|
When I route I should get
|
||||||
| from | to | status | message |
|
| from | to | status | message |
|
||||||
| a | d | 400 | Exclude flag combination is not supported. |
|
| a | d | 400 | Exclude flag combination is not supported. |
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: Testbot - exclude with invalid exclude class name
|
Scenario: Testbot - exclude with invalid exclude class name
|
||||||
Given the query options
|
Given the query options
|
||||||
| exclude | foo |
|
| exclude | foo |
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
@routing @testbot @via
|
||||||
|
Feature: Force routing steps
|
||||||
|
Background:
|
||||||
|
Given the profile "testbot"
|
||||||
|
|
||||||
|
Scenario: Direct routes with waypoints on same edge
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
1 2
|
||||||
|
a-------b
|
||||||
|
| |
|
||||||
|
d-------c
|
||||||
|
| |
|
||||||
|
e-------f
|
||||||
|
3 4
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | oneway |
|
||||||
|
| ab | no |
|
||||||
|
| ad | no |
|
||||||
|
| bc | no |
|
||||||
|
| cf | no |
|
||||||
|
| dc | no |
|
||||||
|
| de | no |
|
||||||
|
| ef | yes |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | approaches | weight | route |
|
||||||
|
| 1,2 | | 20 | ab,ab |
|
||||||
|
| 1,2 | curb curb | 100 | ab,ad,dc,bc,ab |
|
||||||
|
| 2,1 | | 20 | ab,ab |
|
||||||
|
| 2,1 | opposite opposite | 100 | ab,bc,dc,ad,ab |
|
||||||
|
| 3,4 | | 20 | ef,ef |
|
||||||
|
| 4,3 | | 100 | ef,cf,dc,de,ef |
|
||||||
|
|
||||||
|
Scenario: Via routes with waypoints on same edge
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
1 2
|
||||||
|
a-------b
|
||||||
|
| |
|
||||||
|
d-5-----c
|
||||||
|
| |
|
||||||
|
e-------f
|
||||||
|
3 4
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | oneway |
|
||||||
|
| ab | no |
|
||||||
|
| ad | no |
|
||||||
|
| bc | no |
|
||||||
|
| cf | no |
|
||||||
|
| dc | no |
|
||||||
|
| de | no |
|
||||||
|
| ef | yes |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | approaches | weight | route |
|
||||||
|
| 5,1,2 | | 59.8 | dc,ad,ab,ab,ab |
|
||||||
|
| 5,1,2 | unrestricted curb curb | 180.2 | dc,bc,ab,ab,ab,ad,dc,bc,ab |
|
||||||
|
| 5,2,1 | | 80.2 | dc,bc,ab,ab,ab |
|
||||||
|
| 5,2,1 | unrestricted opposite opposite | 159.8 | dc,ad,ab,ab,ab,bc,dc,ad,ab |
|
||||||
|
| 5,3,4 | | 59.8 | dc,de,ef,ef,ef |
|
||||||
|
| 5,4,3 | | 159.8 | dc,de,ef,ef,ef,cf,dc,de,ef |
|
||||||
|
|
||||||
|
|
||||||
|
Scenario: [U-turns allowed] Via routes with waypoints on same edge
|
||||||
|
Given the node map
|
||||||
|
"""
|
||||||
|
1 2
|
||||||
|
a-------b
|
||||||
|
| |
|
||||||
|
d-5-----c
|
||||||
|
| |
|
||||||
|
e-------f
|
||||||
|
3 4
|
||||||
|
"""
|
||||||
|
|
||||||
|
And the ways
|
||||||
|
| nodes | oneway |
|
||||||
|
| ab | no |
|
||||||
|
| ad | no |
|
||||||
|
| bc | no |
|
||||||
|
| cf | no |
|
||||||
|
| dc | no |
|
||||||
|
| de | no |
|
||||||
|
| ef | yes |
|
||||||
|
|
||||||
|
And the query options
|
||||||
|
| continue_straight | false |
|
||||||
|
|
||||||
|
When I route I should get
|
||||||
|
| waypoints | approaches | weight | route |
|
||||||
|
| 5,1,2 | | 59.8 | dc,ad,ab,ab,ab |
|
||||||
|
| 5,1,2 | unrestricted curb curb | 180.2 | dc,bc,ab,ab,ab,ad,dc,bc,ab |
|
||||||
|
| 5,2,1 | | 79.8 | dc,ad,ab,ab,ab,ab |
|
||||||
|
| 5,2,1 | unrestricted opposite opposite | 159.8 | dc,ad,ab,ab,ab,bc,dc,ad,ab |
|
||||||
|
| 5,3,4 | | 59.8 | dc,de,ef,ef,ef |
|
||||||
|
| 5,4,3 | | 159.8 | dc,de,ef,ef,ef,cf,dc,de,ef |
|
||||||
@@ -32,7 +32,6 @@ Feature: Ways of loading data
|
|||||||
Then stderr should be empty
|
Then stderr should be empty
|
||||||
And it should exit successfully
|
And it should exit successfully
|
||||||
|
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: osrm-datastore - Fail if no shared memory blocks are loaded
|
Scenario: osrm-datastore - Fail if no shared memory blocks are loaded
|
||||||
When I run "osrm-datastore --spring-clean" with input "Y"
|
When I run "osrm-datastore --spring-clean" with input "Y"
|
||||||
And I try to run "osrm-routed --shared-memory=1"
|
And I try to run "osrm-routed --shared-memory=1"
|
||||||
|
|||||||
@@ -563,7 +563,6 @@ Feature: Basic Map Matching
|
|||||||
| trace | timestamps | code |
|
| trace | timestamps | code |
|
||||||
| abcd | 0 1 62 63 | NoMatch |
|
| abcd | 0 1 62 63 | NoMatch |
|
||||||
|
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: Testbot - Map matching invalid waypoints
|
Scenario: Testbot - Map matching invalid waypoints
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
@@ -581,7 +580,6 @@ Feature: Basic Map Matching
|
|||||||
| trace | code |
|
| trace | code |
|
||||||
| abcd | InvalidOptions |
|
| abcd | InvalidOptions |
|
||||||
|
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: Matching fail with waypoints param missing start/end
|
Scenario: Matching fail with waypoints param missing start/end
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
@@ -790,7 +788,7 @@ Feature: Basic Map Matching
|
|||||||
| 1234 | 1.000135,1,1.000225,1,1.000404,1,1.000449,1 | 1:2:0.4 | 1:2:0.4 | 3.4 |
|
| 1234 | 1.000135,1,1.000225,1,1.000404,1,1.000449,1 | 1:2:0.4 | 1:2:0.4 | 3.4 |
|
||||||
| 4321 | 1.000449,1,1.000404,1,1.000225,1,1.000135,1 | 0.4:2:1 | 0.4:2:1 | 3.4 |
|
| 4321 | 1.000449,1,1.000404,1,1.000225,1,1.000135,1 | 0.4:2:1 | 0.4:2:1 | 3.4 |
|
||||||
|
|
||||||
@match @testbot @skip_on_routed_js
|
@match @testbot
|
||||||
Scenario: Regression test - add source phantom properly (two phantoms on one edge)
|
Scenario: Regression test - add source phantom properly (two phantoms on one edge)
|
||||||
Given the profile "testbot"
|
Given the profile "testbot"
|
||||||
Given a grid size of 10 meters
|
Given a grid size of 10 meters
|
||||||
|
|||||||
@@ -570,8 +570,7 @@ Feature: Snapping at intersections
|
|||||||
| a,f,k | ac,cf,cf,fj,kj,kj | 132.8s | 132.8 |
|
| a,f,k | ac,cf,cf,fj,kj,kj | 132.8s | 132.8 |
|
||||||
| k,f | ik,fi,fi | 54.3s | 54.3 |
|
| k,f | ik,fi,fi | 54.3s | 54.3 |
|
||||||
| f,a | ef,ae,ae | 66.6s | 66.6 |
|
| f,a | ef,ae,ae | 66.6s | 66.6 |
|
||||||
| k,f,a | kj,fj,fj,ef,ae,ae | 141.4s +- 1e-7 | 141.4 +- 1e-7 |
|
| k,f,a | kj,fj,fj,ef,ae,ae | 141.4s | 141.4 |
|
||||||
|
|
||||||
|
|
||||||
When I request a travel time matrix I should get
|
When I request a travel time matrix I should get
|
||||||
| | a | f | k |
|
| | a | f | k |
|
||||||
@@ -627,4 +626,4 @@ Feature: Snapping at intersections
|
|||||||
| a,f,k | ad,df,df,fj,kj,kj | 105.6s | 105.6 |
|
| a,f,k | ad,df,df,fj,kj,kj | 105.6s | 105.6 |
|
||||||
| k,f | ik,fi,fi | 54.3s | 54.3 |
|
| k,f | ik,fi,fi | 54.3s | 54.3 |
|
||||||
| f,a | ef,ae,ae | 66.6s | 66.6 |
|
| f,a | ef,ae,ae | 66.6s | 66.6 |
|
||||||
| k,f,a | ik,fi,fi,ef,ae,ae | 120.9s +- 1e-7 | 120.9 +- 1e-7 |
|
| k,f,a | ik,fi,fi,ef,ae,ae | 120.9s | 120.9 |
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Feature: Status messages
|
|||||||
| from | to | route | status | message |
|
| from | to | route | status | message |
|
||||||
| a | b | ab,ab | 200 | |
|
| a | b | ab,ab | 200 | |
|
||||||
| b | a | ab,ab | 200 | |
|
| b | a | ab,ab | 200 | |
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: No route found
|
Scenario: No route found
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
@@ -39,7 +39,6 @@ Feature: Status messages
|
|||||||
| a | c | | 400 | Impossible route between points |
|
| a | c | | 400 | Impossible route between points |
|
||||||
| b | d | | 400 | Impossible route between points |
|
| b | d | | 400 | Impossible route between points |
|
||||||
|
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: Malformed requests
|
Scenario: Malformed requests
|
||||||
Given the node locations
|
Given the node locations
|
||||||
| node | lat | lon |
|
| node | lat | lon |
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ Feature: Basic trip planning
|
|||||||
Background:
|
Background:
|
||||||
Given the profile "testbot"
|
Given the profile "testbot"
|
||||||
Given a grid size of 10 meters
|
Given a grid size of 10 meters
|
||||||
|
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: Testbot - Trip: Invalid options (like was in test suite for a long time)
|
Scenario: Testbot - Trip: Invalid options (like was in test suite for a long time)
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
@@ -223,7 +222,7 @@ Feature: Basic trip planning
|
|||||||
| waypoints | trips | roundtrip | durations |
|
| 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 | lkjihgfedcbal | true | 22 |
|
||||||
| a,b,c,d,e,f,g,h,i,j,k,l | cbakjihgfedl | false | 19 |
|
| a,b,c,d,e,f,g,h,i,j,k,l | cbakjihgfedl | false | 19 |
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: Testbot - Trip: Unroutable roundtrip with waypoints (less than 10)
|
Scenario: Testbot - Trip: Unroutable roundtrip with waypoints (less than 10)
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
@@ -241,7 +240,7 @@ Feature: Basic trip planning
|
|||||||
| waypoints | status | message |
|
| waypoints | status | message |
|
||||||
| a,b,c,d | NoTrips | No trip visiting all destinations possible. |
|
| a,b,c,d | NoTrips | No trip visiting all destinations possible. |
|
||||||
|
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: Testbot - Trip: Unroutable roundtrip with waypoints (more than 10)
|
Scenario: Testbot - Trip: Unroutable roundtrip with waypoints (more than 10)
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
@@ -279,7 +278,6 @@ Feature: Basic trip planning
|
|||||||
| a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p | NoTrips | No trip visiting all destinations possible. |
|
| a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p | NoTrips | No trip visiting all destinations possible. |
|
||||||
|
|
||||||
# Test TFSE
|
# Test TFSE
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: Testbot - Trip: TFSE with errors
|
Scenario: Testbot - Trip: TFSE with errors
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
@@ -373,7 +371,7 @@ Feature: Basic trip planning
|
|||||||
| waypoints | source | destination | roundtrip | trips |
|
| waypoints | source | destination | roundtrip | trips |
|
||||||
| a,b,d,e,c | first | last | true | abedca |
|
| a,b,d,e,c | first | last | true | abedca |
|
||||||
|
|
||||||
@skip_on_routed_js
|
|
||||||
Scenario: Testbot - Trip: midway points in isolated roads should return no trips
|
Scenario: Testbot - Trip: midway points in isolated roads should return no trips
|
||||||
Given the node map
|
Given the node map
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -52,11 +52,11 @@ Feature: Weight tests
|
|||||||
| abc |
|
| abc |
|
||||||
|
|
||||||
When I route I should get
|
When I route I should get
|
||||||
| waypoints | route | distances | weights | times | a:distance | a:duration | a:weight | a:speed |
|
| waypoints | route | distances | weights | times | a:distance | a:duration | a:weight | a:speed |
|
||||||
| s,t | abc,abc | 20m,0m | 2,0 | 2s,0s | 20.03462663 +- 1e-7 | 2 | 2 | 10 |
|
| s,t | abc,abc | 20m,0m | 2,0 | 2s,0s | 20.03462663 | 2 | 2 | 10 |
|
||||||
| t,s | abc,abc | 20m,0m | 2,0 | 2s,0s | 20.03462663 +- 1e-7 | 2 | 2 | 10 |
|
| t,s | abc,abc | 20m,0m | 2,0 | 2s,0s | 20.03462663 | 2 | 2 | 10 |
|
||||||
| s,e | abc,abc | 40m,0m | 3.9,0 | 3.9s,0s | 29.94063646:10.01731331 +- 1e-7 | 3:0.9 | 3:0.9 | 10:11.1 |
|
| s,e | abc,abc | 40m,0m | 3.9,0 | 3.9s,0s | 29.94063646:10.01731331 | 3:0.9 | 3:0.9 | 10:11.1 |
|
||||||
| e,s | abc,abc | 40m,0m | 3.9,0 | 3.9s,0s | 10.01731331:29.94063646 +- 1e-7 | 0.9:3 | 0.9:3 | 11.1:10 |
|
| e,s | abc,abc | 40m,0m | 3.9,0 | 3.9s,0s | 10.01731331:29.94063646 | 0.9:3 | 0.9:3 | 11.1:10 |
|
||||||
|
|
||||||
|
|
||||||
Scenario: Step weights -- way_function: fail if no weight or weight_per_meter property
|
Scenario: Step weights -- way_function: fail if no weight or weight_per_meter property
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
Feature: Tile service
|
|
||||||
Background:
|
|
||||||
Given the profile "testbot"
|
|
||||||
Scenario: Smoke test
|
|
||||||
Given the origin 52.5212,13.3919
|
|
||||||
Given the node map
|
|
||||||
"""
|
|
||||||
a b
|
|
||||||
"""
|
|
||||||
And the ways
|
|
||||||
| nodes |
|
|
||||||
| ab |
|
|
||||||
When I request /tile/v1/testbot/tile(8800,5373,14).mvt
|
|
||||||
Then HTTP code should be 200
|
|
||||||
@@ -61,10 +61,12 @@ inline auto contractExcludableGraph(ContractorGraph contractor_graph_,
|
|||||||
// Add all non-core edges to container
|
// Add all non-core edges to container
|
||||||
{
|
{
|
||||||
auto non_core_edges = toEdges<QueryEdge>(contractor_graph);
|
auto non_core_edges = toEdges<QueryEdge>(contractor_graph);
|
||||||
auto new_end =
|
auto new_end = std::remove_if(non_core_edges.begin(),
|
||||||
std::remove_if(non_core_edges.begin(), non_core_edges.end(), [&](const auto &edge) {
|
non_core_edges.end(),
|
||||||
return is_shared_core[edge.source] && is_shared_core[edge.target];
|
[&](const auto &edge) {
|
||||||
});
|
return is_shared_core[edge.source] &&
|
||||||
|
is_shared_core[edge.target];
|
||||||
|
});
|
||||||
non_core_edges.resize(new_end - non_core_edges.begin());
|
non_core_edges.resize(new_end - non_core_edges.begin());
|
||||||
edge_container.Insert(std::move(non_core_edges));
|
edge_container.Insert(std::move(non_core_edges));
|
||||||
|
|
||||||
@@ -75,8 +77,8 @@ inline auto contractExcludableGraph(ContractorGraph contractor_graph_,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract core graph for further contraction
|
// Extract core graph for further contraction
|
||||||
shared_core_graph = contractor_graph.Filter(
|
shared_core_graph = contractor_graph.Filter([&is_shared_core](const NodeID node)
|
||||||
[&is_shared_core](const NodeID node) { return is_shared_core[node]; });
|
{ return is_shared_core[node]; });
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &filter : filters)
|
for (const auto &filter : filters)
|
||||||
|
|||||||
@@ -89,37 +89,40 @@ struct ContractedEdgeContainer
|
|||||||
|
|
||||||
// Remove all edges that are contained in the old set of edges and set the appropriate flag.
|
// Remove all edges that are contained in the old set of edges and set the appropriate flag.
|
||||||
auto new_end =
|
auto new_end =
|
||||||
std::remove_if(new_edges.begin(), new_edges.end(), [&](const QueryEdge &edge) {
|
std::remove_if(new_edges.begin(),
|
||||||
// check if the new edge would be sorted before the currend old edge
|
new_edges.end(),
|
||||||
// if so it is not contained yet in the set of old edges
|
[&](const QueryEdge &edge)
|
||||||
if (edge_iter == edge_end || mergeCompare(edge, *edge_iter))
|
{
|
||||||
{
|
// check if the new edge would be sorted before the currend old edge
|
||||||
return false;
|
// if so it is not contained yet in the set of old edges
|
||||||
}
|
if (edge_iter == edge_end || mergeCompare(edge, *edge_iter))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// find the first old edge that is equal or greater then the new edge
|
// find the first old edge that is equal or greater then the new edge
|
||||||
while (edge_iter != edge_end && mergeCompare(*edge_iter, edge))
|
while (edge_iter != edge_end && mergeCompare(*edge_iter, edge))
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(flags_iter != flags.end());
|
BOOST_ASSERT(flags_iter != flags.end());
|
||||||
edge_iter++;
|
edge_iter++;
|
||||||
flags_iter++;
|
flags_iter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// all new edges will be sorted after the old edges
|
// all new edges will be sorted after the old edges
|
||||||
if (edge_iter == edge_end)
|
if (edge_iter == edge_end)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(edge_iter != edge_end);
|
BOOST_ASSERT(edge_iter != edge_end);
|
||||||
if (mergable(edge, *edge_iter))
|
if (mergable(edge, *edge_iter))
|
||||||
{
|
{
|
||||||
*flags_iter = *flags_iter | flag;
|
*flags_iter = *flags_iter | flag;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
BOOST_ASSERT(mergeCompare(edge, *edge_iter));
|
BOOST_ASSERT(mergeCompare(edge, *edge_iter));
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
// append new edges
|
// append new edges
|
||||||
edges.insert(edges.end(), new_edges.begin(), new_end);
|
edges.insert(edges.end(), new_edges.begin(), new_end);
|
||||||
@@ -132,10 +135,10 @@ struct ContractedEdgeContainer
|
|||||||
// enforce sorting for next merge step
|
// enforce sorting for next merge step
|
||||||
std::vector<unsigned> ordering(edges_size);
|
std::vector<unsigned> ordering(edges_size);
|
||||||
std::iota(ordering.begin(), ordering.end(), 0);
|
std::iota(ordering.begin(), ordering.end(), 0);
|
||||||
tbb::parallel_sort(
|
tbb::parallel_sort(ordering.begin(),
|
||||||
ordering.begin(), ordering.end(), [&](const auto lhs_idx, const auto rhs_idx) {
|
ordering.end(),
|
||||||
return mergeCompare(edges[lhs_idx], edges[rhs_idx]);
|
[&](const auto lhs_idx, const auto rhs_idx)
|
||||||
});
|
{ return mergeCompare(edges[lhs_idx], edges[rhs_idx]); });
|
||||||
auto permutation = util::orderingToPermutation(ordering);
|
auto permutation = util::orderingToPermutation(ordering);
|
||||||
|
|
||||||
util::inplacePermutation(edges.begin(), edges.end(), permutation);
|
util::inplacePermutation(edges.begin(), edges.end(), permutation);
|
||||||
|
|||||||
@@ -31,8 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "storage/io_config.hpp"
|
#include "storage/io_config.hpp"
|
||||||
#include "updater/updater_config.hpp"
|
#include "updater/updater_config.hpp"
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <filesystem>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace osrm::contractor
|
namespace osrm::contractor
|
||||||
@@ -47,7 +46,7 @@ struct ContractorConfig final : storage::IOConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Infer the output names from the path of the .osrm file
|
// Infer the output names from the path of the .osrm file
|
||||||
void UseDefaultOutputNames(const boost::filesystem::path &base)
|
void UseDefaultOutputNames(const std::filesystem::path &base)
|
||||||
{
|
{
|
||||||
IOConfig::UseDefaultOutputNames(base);
|
IOConfig::UseDefaultOutputNames(base);
|
||||||
updater_config.UseDefaultOutputNames(base);
|
updater_config.UseDefaultOutputNames(base);
|
||||||
|
|||||||
@@ -1,128 +0,0 @@
|
|||||||
#ifndef ITERATOR_BASED_CRC32_H
|
|
||||||
#define ITERATOR_BASED_CRC32_H
|
|
||||||
|
|
||||||
#if defined(__x86_64__) && !defined(__MINGW64__)
|
|
||||||
#include <cpuid.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/crc.hpp> // for boost::crc_32_type
|
|
||||||
|
|
||||||
#include <iterator>
|
|
||||||
|
|
||||||
namespace osrm::contractor
|
|
||||||
{
|
|
||||||
|
|
||||||
class IteratorbasedCRC32
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool UsingHardware() const { return use_hardware_implementation; }
|
|
||||||
|
|
||||||
IteratorbasedCRC32() : crc(0) { use_hardware_implementation = DetectHardwareSupport(); }
|
|
||||||
|
|
||||||
template <class Iterator> unsigned operator()(Iterator iter, const Iterator end)
|
|
||||||
{
|
|
||||||
unsigned crc = 0;
|
|
||||||
while (iter != end)
|
|
||||||
{
|
|
||||||
using value_type = typename std::iterator_traits<Iterator>::value_type;
|
|
||||||
const char *data = reinterpret_cast<const char *>(&(*iter));
|
|
||||||
|
|
||||||
if (use_hardware_implementation)
|
|
||||||
{
|
|
||||||
crc = ComputeInHardware(data, sizeof(value_type));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
crc = ComputeInSoftware(data, sizeof(value_type));
|
|
||||||
}
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool DetectHardwareSupport() const
|
|
||||||
{
|
|
||||||
static const int sse42_bit = 0x00100000;
|
|
||||||
const unsigned ecx = cpuid();
|
|
||||||
const bool sse42_found = (ecx & sse42_bit) != 0;
|
|
||||||
return sse42_found;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned ComputeInSoftware(const char *str, unsigned len)
|
|
||||||
{
|
|
||||||
crc_processor.process_bytes(str, len);
|
|
||||||
return crc_processor.checksum();
|
|
||||||
}
|
|
||||||
|
|
||||||
// adapted from http://byteworm.com/2010/10/13/crc32/
|
|
||||||
unsigned ComputeInHardware(const char *str, unsigned len)
|
|
||||||
{
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
unsigned q = len / sizeof(unsigned);
|
|
||||||
unsigned r = len % sizeof(unsigned);
|
|
||||||
unsigned *p = (unsigned *)str;
|
|
||||||
|
|
||||||
// crc=0;
|
|
||||||
while (q--)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__(".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
|
|
||||||
: "=S"(crc)
|
|
||||||
: "0"(crc), "c"(*p));
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
|
|
||||||
str = reinterpret_cast<char *>(p);
|
|
||||||
while (r--)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__(".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
|
|
||||||
: "=S"(crc)
|
|
||||||
: "0"(crc), "c"(*str));
|
|
||||||
++str;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
(void)str;
|
|
||||||
(void)len;
|
|
||||||
#endif
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned cpuid() const
|
|
||||||
{
|
|
||||||
unsigned eax = 0, ebx = 0, ecx = 0, edx = 0;
|
|
||||||
// on X64 this calls hardware cpuid(.) instr. otherwise a dummy impl.
|
|
||||||
__get_cpuid(1, &eax, &ebx, &ecx, &edx);
|
|
||||||
return ecx;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__MINGW64__) || defined(_MSC_VER) || !defined(__x86_64__)
|
|
||||||
inline void __get_cpuid(int /*param*/,
|
|
||||||
unsigned * /*eax*/,
|
|
||||||
unsigned * /*ebx*/,
|
|
||||||
unsigned *ecx,
|
|
||||||
unsigned * /*edx*/) const
|
|
||||||
{
|
|
||||||
*ecx = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> crc_processor;
|
|
||||||
unsigned crc;
|
|
||||||
bool use_hardware_implementation;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RangebasedCRC32
|
|
||||||
{
|
|
||||||
template <typename Iteratable> unsigned operator()(const Iteratable &iterable)
|
|
||||||
{
|
|
||||||
return crc32(std::begin(iterable), std::end(iterable));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UsingHardware() const { return crc32.UsingHardware(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
IteratorbasedCRC32 crc32;
|
|
||||||
};
|
|
||||||
} // namespace osrm::contractor
|
|
||||||
|
|
||||||
#endif /* ITERATOR_BASED_CRC32_H */
|
|
||||||
@@ -9,7 +9,7 @@ namespace osrm::contractor::files
|
|||||||
{
|
{
|
||||||
// reads .osrm.hsgr file
|
// reads .osrm.hsgr file
|
||||||
template <typename ContractedMetricT>
|
template <typename ContractedMetricT>
|
||||||
inline void readGraph(const boost::filesystem::path &path,
|
inline void readGraph(const std::filesystem::path &path,
|
||||||
std::unordered_map<std::string, ContractedMetricT> &metrics,
|
std::unordered_map<std::string, ContractedMetricT> &metrics,
|
||||||
std::uint32_t &connectivity_checksum)
|
std::uint32_t &connectivity_checksum)
|
||||||
{
|
{
|
||||||
@@ -30,7 +30,7 @@ inline void readGraph(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// writes .osrm.hsgr file
|
// writes .osrm.hsgr file
|
||||||
template <typename ContractedMetricT>
|
template <typename ContractedMetricT>
|
||||||
inline void writeGraph(const boost::filesystem::path &path,
|
inline void writeGraph(const std::filesystem::path &path,
|
||||||
const std::unordered_map<std::string, ContractedMetricT> &metrics,
|
const std::unordered_map<std::string, ContractedMetricT> &metrics,
|
||||||
const std::uint32_t connectivity_checksum)
|
const std::uint32_t connectivity_checksum)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -122,7 +122,8 @@ class CellCustomizer
|
|||||||
for (std::size_t level = 1; level < partition.GetNumberOfLevels(); ++level)
|
for (std::size_t level = 1; level < partition.GetNumberOfLevels(); ++level)
|
||||||
{
|
{
|
||||||
tbb::parallel_for(tbb::blocked_range<std::size_t>(0, partition.GetNumberOfCells(level)),
|
tbb::parallel_for(tbb::blocked_range<std::size_t>(0, partition.GetNumberOfCells(level)),
|
||||||
[&](const tbb::blocked_range<std::size_t> &range) {
|
[&](const tbb::blocked_range<std::size_t> &range)
|
||||||
|
{
|
||||||
auto &heap = heaps.local();
|
auto &heap = heaps.local();
|
||||||
for (auto id = range.begin(), end = range.end(); id != end; ++id)
|
for (auto id = range.begin(), end = range.end(); id != end; ++id)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#ifndef OSRM_CUSTOMIZE_CUSTOMIZER_CONFIG_HPP
|
#ifndef OSRM_CUSTOMIZE_CUSTOMIZER_CONFIG_HPP
|
||||||
#define OSRM_CUSTOMIZE_CUSTOMIZER_CONFIG_HPP
|
#define OSRM_CUSTOMIZE_CUSTOMIZER_CONFIG_HPP
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <filesystem>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "storage/io_config.hpp"
|
#include "storage/io_config.hpp"
|
||||||
@@ -27,7 +26,7 @@ struct CustomizationConfig final : storage::IOConfig
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void UseDefaultOutputNames(const boost::filesystem::path &base)
|
void UseDefaultOutputNames(const std::filesystem::path &base)
|
||||||
{
|
{
|
||||||
IOConfig::UseDefaultOutputNames(base);
|
IOConfig::UseDefaultOutputNames(base);
|
||||||
updater_config.UseDefaultOutputNames(base);
|
updater_config.UseDefaultOutputNames(base);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include "storage/shared_memory_ownership.hpp"
|
#include "storage/shared_memory_ownership.hpp"
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <filesystem>
|
||||||
|
|
||||||
namespace osrm::customizer
|
namespace osrm::customizer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace osrm::customizer::files
|
|||||||
|
|
||||||
// reads .osrm.cell_metrics file
|
// reads .osrm.cell_metrics file
|
||||||
template <typename CellMetricT>
|
template <typename CellMetricT>
|
||||||
inline void readCellMetrics(const boost::filesystem::path &path,
|
inline void readCellMetrics(const std::filesystem::path &path,
|
||||||
std::unordered_map<std::string, std::vector<CellMetricT>> &metrics)
|
std::unordered_map<std::string, std::vector<CellMetricT>> &metrics)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<CellMetricView, CellMetricT>::value ||
|
static_assert(std::is_same<CellMetricView, CellMetricT>::value ||
|
||||||
@@ -44,7 +44,7 @@ inline void readCellMetrics(const boost::filesystem::path &path,
|
|||||||
// writes .osrm.cell_metrics file
|
// writes .osrm.cell_metrics file
|
||||||
template <typename CellMetricT>
|
template <typename CellMetricT>
|
||||||
inline void
|
inline void
|
||||||
writeCellMetrics(const boost::filesystem::path &path,
|
writeCellMetrics(const std::filesystem::path &path,
|
||||||
const std::unordered_map<std::string, std::vector<CellMetricT>> &metrics)
|
const std::unordered_map<std::string, std::vector<CellMetricT>> &metrics)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<CellMetricView, CellMetricT>::value ||
|
static_assert(std::is_same<CellMetricView, CellMetricT>::value ||
|
||||||
@@ -72,7 +72,7 @@ writeCellMetrics(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// reads .osrm.mldgr file
|
// reads .osrm.mldgr file
|
||||||
template <typename MultiLevelGraphT>
|
template <typename MultiLevelGraphT>
|
||||||
inline void readGraph(const boost::filesystem::path &path,
|
inline void readGraph(const std::filesystem::path &path,
|
||||||
MultiLevelGraphT &graph,
|
MultiLevelGraphT &graph,
|
||||||
std::uint32_t &connectivity_checksum)
|
std::uint32_t &connectivity_checksum)
|
||||||
{
|
{
|
||||||
@@ -88,7 +88,7 @@ inline void readGraph(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// writes .osrm.mldgr file
|
// writes .osrm.mldgr file
|
||||||
template <typename MultiLevelGraphT>
|
template <typename MultiLevelGraphT>
|
||||||
inline void writeGraph(const boost::filesystem::path &path,
|
inline void writeGraph(const std::filesystem::path &path,
|
||||||
const MultiLevelGraphT &graph,
|
const MultiLevelGraphT &graph,
|
||||||
const std::uint32_t connectivity_checksum)
|
const std::uint32_t connectivity_checksum)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ class BaseAPI
|
|||||||
util::json::Array waypoints;
|
util::json::Array waypoints;
|
||||||
waypoints.values.resize(parameters.coordinates.size());
|
waypoints.values.resize(parameters.coordinates.size());
|
||||||
|
|
||||||
boost::range::transform(
|
boost::range::transform(waypoint_candidates,
|
||||||
waypoint_candidates,
|
waypoints.values.begin(),
|
||||||
waypoints.values.begin(),
|
[this](const PhantomNodeCandidates &candidates)
|
||||||
[this](const PhantomNodeCandidates &candidates) { return MakeWaypoint(candidates); });
|
{ return MakeWaypoint(candidates); });
|
||||||
return waypoints;
|
return waypoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,9 +104,8 @@ class BaseAPI
|
|||||||
std::transform(waypoint_candidates.begin(),
|
std::transform(waypoint_candidates.begin(),
|
||||||
waypoint_candidates.end(),
|
waypoint_candidates.end(),
|
||||||
waypoints.begin(),
|
waypoints.begin(),
|
||||||
[this, builder](const PhantomNodeCandidates &candidates) {
|
[this, builder](const PhantomNodeCandidates &candidates)
|
||||||
return MakeWaypoint(builder, candidates)->Finish();
|
{ return MakeWaypoint(builder, candidates)->Finish(); });
|
||||||
});
|
|
||||||
return builder->CreateVector(waypoints);
|
return builder->CreateVector(waypoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ namespace osrm::engine::api
|
|||||||
* optional per coordinate
|
* optional per coordinate
|
||||||
* - bearings: limits the search for segments in the road network to given bearing(s) in degree
|
* - bearings: limits the search for segments in the road network to given bearing(s) in degree
|
||||||
* towards true north in clockwise direction, optional per coordinate
|
* towards true north in clockwise direction, optional per coordinate
|
||||||
* - approaches: force the phantom node to start towards the node with the road country side.
|
* - approaches: force the phantom node to start towards the node with the road country side or
|
||||||
|
* its opposite
|
||||||
*
|
*
|
||||||
* \see OSRM, Coordinate, Hint, Bearing, RouteParameters, TableParameters,
|
* \see OSRM, Coordinate, Hint, Bearing, RouteParameters, TableParameters,
|
||||||
* NearestParameters, TripParameters, MatchParameters and TileParameters
|
* NearestParameters, TripParameters, MatchParameters and TileParameters
|
||||||
@@ -111,7 +112,8 @@ struct BaseParameters
|
|||||||
(approaches.empty() || approaches.size() == coordinates.size()) &&
|
(approaches.empty() || approaches.size() == coordinates.size()) &&
|
||||||
std::all_of(bearings.begin(),
|
std::all_of(bearings.begin(),
|
||||||
bearings.end(),
|
bearings.end(),
|
||||||
[](const boost::optional<Bearing> &bearing_and_range) {
|
[](const boost::optional<Bearing> &bearing_and_range)
|
||||||
|
{
|
||||||
if (bearing_and_range)
|
if (bearing_and_range)
|
||||||
{
|
{
|
||||||
return bearing_and_range->IsValid();
|
return bearing_and_range->IsValid();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#define ENGINE_API_BASE_RESULT_HPP
|
#define ENGINE_API_BASE_RESULT_HPP
|
||||||
|
|
||||||
#include <flatbuffers/flatbuffers.h>
|
#include <flatbuffers/flatbuffers.h>
|
||||||
#include <mapbox/variant.hpp>
|
#include <variant>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -10,8 +10,7 @@
|
|||||||
|
|
||||||
namespace osrm::engine::api
|
namespace osrm::engine::api
|
||||||
{
|
{
|
||||||
using ResultT =
|
using ResultT = std::variant<util::json::Object, std::string, flatbuffers::FlatBufferBuilder>;
|
||||||
mapbox::util::variant<util::json::Object, std::string, flatbuffers::FlatBufferBuilder>;
|
|
||||||
} // namespace osrm::engine::api
|
} // namespace osrm::engine::api
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection
|
|||||||
return intersection.lanes.lanes_in_turn > 0;
|
return intersection.lanes.lanes_in_turn > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
util::json::Array coordinateToLonLat(const util::Coordinate &coordinate);
|
util::json::Value coordinateToLonLat(const util::Coordinate &coordinate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that a bearing value is a whole number, and clamped to the range 0-359
|
* Ensures that a bearing value is a whole number, and clamped to the range 0-359
|
||||||
@@ -79,7 +79,7 @@ util::json::Object makeGeoJSONGeometry(ForwardIter begin, ForwardIter end)
|
|||||||
coordinates.values.push_back(location);
|
coordinates.values.push_back(location);
|
||||||
coordinates.values.push_back(location);
|
coordinates.values.push_back(location);
|
||||||
}
|
}
|
||||||
geojson.values["coordinates"] = std::move(coordinates);
|
geojson.values["coordinates"] = util::json::Value{std::move(coordinates)};
|
||||||
|
|
||||||
return geojson;
|
return geojson;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,14 +30,14 @@ class MatchAPI final : public RouteAPI
|
|||||||
osrm::engine::api::ResultT &response) const
|
osrm::engine::api::ResultT &response) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(sub_matchings.size() == sub_routes.size());
|
BOOST_ASSERT(sub_matchings.size() == sub_routes.size());
|
||||||
if (response.is<flatbuffers::FlatBufferBuilder>())
|
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
|
||||||
{
|
{
|
||||||
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
|
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
|
||||||
MakeResponse(sub_matchings, sub_routes, fb_result);
|
MakeResponse(sub_matchings, sub_routes, fb_result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto &json_result = response.get<util::json::Object>();
|
auto &json_result = std::get<util::json::Object>(response);
|
||||||
MakeResponse(sub_matchings, sub_routes, json_result);
|
MakeResponse(sub_matchings, sub_routes, json_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,9 +52,10 @@ class MatchAPI final : public RouteAPI
|
|||||||
data_version_string = fb_result.CreateString(data_timestamp);
|
data_version_string = fb_result.CreateString(data_timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto response = MakeFBResponse(sub_routes, fb_result, [this, &fb_result, &sub_matchings]() {
|
auto response = MakeFBResponse(sub_routes,
|
||||||
return MakeTracepoints(fb_result, sub_matchings);
|
fb_result,
|
||||||
});
|
[this, &fb_result, &sub_matchings]()
|
||||||
|
{ return MakeTracepoints(fb_result, sub_matchings); });
|
||||||
|
|
||||||
if (!data_timestamp.empty())
|
if (!data_timestamp.empty())
|
||||||
{
|
{
|
||||||
@@ -76,19 +77,19 @@ class MatchAPI final : public RouteAPI
|
|||||||
sub_routes[index].unpacked_path_segments,
|
sub_routes[index].unpacked_path_segments,
|
||||||
sub_routes[index].source_traversed_in_reverse,
|
sub_routes[index].source_traversed_in_reverse,
|
||||||
sub_routes[index].target_traversed_in_reverse);
|
sub_routes[index].target_traversed_in_reverse);
|
||||||
route.values["confidence"] = sub_matchings[index].confidence;
|
route.values.emplace("confidence", sub_matchings[index].confidence);
|
||||||
routes.values.push_back(std::move(route));
|
routes.values.emplace_back(std::move(route));
|
||||||
}
|
}
|
||||||
if (!parameters.skip_waypoints)
|
if (!parameters.skip_waypoints)
|
||||||
{
|
{
|
||||||
response.values["tracepoints"] = MakeTracepoints(sub_matchings);
|
response.values.emplace("tracepoints", MakeTracepoints(sub_matchings));
|
||||||
}
|
}
|
||||||
response.values["matchings"] = std::move(routes);
|
response.values.emplace("matchings", std::move(routes));
|
||||||
response.values["code"] = "Ok";
|
response.values.emplace("code", "Ok");
|
||||||
auto data_timestamp = facade.GetTimestamp();
|
auto data_timestamp = facade.GetTimestamp();
|
||||||
if (!data_timestamp.empty())
|
if (!data_timestamp.empty())
|
||||||
{
|
{
|
||||||
response.values["data_version"] = data_timestamp;
|
response.values.emplace("data_version", data_timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,13 +132,13 @@ class MatchAPI final : public RouteAPI
|
|||||||
|
|
||||||
if (tidy_result.can_be_removed[trace_index])
|
if (tidy_result.can_be_removed[trace_index])
|
||||||
{
|
{
|
||||||
waypoints.push_back(fbresult::WaypointBuilder(fb_result).Finish());
|
waypoints.emplace_back(fbresult::WaypointBuilder(fb_result).Finish());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto matching_index = trace_idx_to_matching_idx[trace_index];
|
auto matching_index = trace_idx_to_matching_idx[trace_index];
|
||||||
if (matching_index.NotMatched())
|
if (matching_index.NotMatched())
|
||||||
{
|
{
|
||||||
waypoints.push_back(fbresult::WaypointBuilder(fb_result).Finish());
|
waypoints.emplace_back(fbresult::WaypointBuilder(fb_result).Finish());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto &phantom =
|
const auto &phantom =
|
||||||
@@ -164,7 +165,7 @@ class MatchAPI final : public RouteAPI
|
|||||||
{
|
{
|
||||||
waypoint->add_waypoint_index(matching_index.point_index);
|
waypoint->add_waypoint_index(matching_index.point_index);
|
||||||
}
|
}
|
||||||
waypoints.push_back(waypoint->Finish());
|
waypoints.emplace_back(waypoint->Finish());
|
||||||
}
|
}
|
||||||
|
|
||||||
return fb_result.CreateVector(waypoints);
|
return fb_result.CreateVector(waypoints);
|
||||||
@@ -185,23 +186,23 @@ class MatchAPI final : public RouteAPI
|
|||||||
{
|
{
|
||||||
if (tidy_result.can_be_removed[trace_index])
|
if (tidy_result.can_be_removed[trace_index])
|
||||||
{
|
{
|
||||||
waypoints.values.push_back(util::json::Null());
|
waypoints.values.emplace_back(util::json::Null());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto matching_index = trace_idx_to_matching_idx[trace_index];
|
auto matching_index = trace_idx_to_matching_idx[trace_index];
|
||||||
if (matching_index.NotMatched())
|
if (matching_index.NotMatched())
|
||||||
{
|
{
|
||||||
waypoints.values.push_back(util::json::Null());
|
waypoints.values.emplace_back(util::json::Null());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto &phantom =
|
const auto &phantom =
|
||||||
sub_matchings[matching_index.sub_matching_index].nodes[matching_index.point_index];
|
sub_matchings[matching_index.sub_matching_index].nodes[matching_index.point_index];
|
||||||
auto waypoint = BaseAPI::MakeWaypoint({phantom});
|
auto waypoint = BaseAPI::MakeWaypoint({phantom});
|
||||||
waypoint.values["matchings_index"] = matching_index.sub_matching_index;
|
waypoint.values.emplace("matchings_index", matching_index.sub_matching_index);
|
||||||
waypoint.values["waypoint_index"] = matching_index.point_index;
|
waypoint.values.emplace("waypoint_index", matching_index.point_index);
|
||||||
waypoint.values["alternatives_count"] =
|
waypoint.values.emplace("alternatives_count",
|
||||||
sub_matchings[matching_index.sub_matching_index]
|
sub_matchings[matching_index.sub_matching_index]
|
||||||
.alternatives_count[matching_index.point_index];
|
.alternatives_count[matching_index.point_index]);
|
||||||
// waypoint indices need to be adjusted if route legs were collapsed
|
// waypoint indices need to be adjusted if route legs were collapsed
|
||||||
// waypoint parameter assumes there is only one match object
|
// waypoint parameter assumes there is only one match object
|
||||||
if (!parameters.waypoints.empty())
|
if (!parameters.waypoints.empty())
|
||||||
@@ -216,7 +217,7 @@ class MatchAPI final : public RouteAPI
|
|||||||
waypoint.values["waypoint_index"] = util::json::Null();
|
waypoint.values["waypoint_index"] = util::json::Null();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
waypoints.values.push_back(std::move(waypoint));
|
waypoints.values.emplace_back(std::move(waypoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
return waypoints;
|
return waypoints;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ struct MatchParameters : public RouteParameters
|
|||||||
MatchParameters(const std::vector<unsigned> ×tamps_,
|
MatchParameters(const std::vector<unsigned> ×tamps_,
|
||||||
GapsType gaps_,
|
GapsType gaps_,
|
||||||
bool tidy_,
|
bool tidy_,
|
||||||
Args &&... args_)
|
Args &&...args_)
|
||||||
: MatchParameters(timestamps_, gaps_, tidy_, {}, std::forward<Args>(args_)...)
|
: MatchParameters(timestamps_, gaps_, tidy_, {}, std::forward<Args>(args_)...)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ struct MatchParameters : public RouteParameters
|
|||||||
GapsType gaps_,
|
GapsType gaps_,
|
||||||
bool tidy_,
|
bool tidy_,
|
||||||
const std::vector<std::size_t> &waypoints_,
|
const std::vector<std::size_t> &waypoints_,
|
||||||
Args &&... args_)
|
Args &&...args_)
|
||||||
: RouteParameters{std::forward<Args>(args_)..., waypoints_}, timestamps{std::move(
|
: RouteParameters{std::forward<Args>(args_)..., waypoints_}, timestamps{std::move(
|
||||||
timestamps_)},
|
timestamps_)},
|
||||||
gaps(gaps_), tidy(tidy_)
|
gaps(gaps_), tidy(tidy_)
|
||||||
|
|||||||
@@ -29,14 +29,14 @@ class NearestAPI final : public BaseAPI
|
|||||||
BOOST_ASSERT(phantom_nodes.size() == 1);
|
BOOST_ASSERT(phantom_nodes.size() == 1);
|
||||||
BOOST_ASSERT(parameters.coordinates.size() == 1);
|
BOOST_ASSERT(parameters.coordinates.size() == 1);
|
||||||
|
|
||||||
if (response.is<flatbuffers::FlatBufferBuilder>())
|
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
|
||||||
{
|
{
|
||||||
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
|
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
|
||||||
MakeResponse(phantom_nodes, fb_result);
|
MakeResponse(phantom_nodes, fb_result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto &json_result = response.get<util::json::Object>();
|
auto &json_result = std::get<util::json::Object>(response);
|
||||||
MakeResponse(phantom_nodes, json_result);
|
MakeResponse(phantom_nodes, json_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,20 +57,20 @@ class NearestAPI final : public BaseAPI
|
|||||||
{
|
{
|
||||||
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
|
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
|
||||||
waypoints.resize(phantom_nodes.front().size());
|
waypoints.resize(phantom_nodes.front().size());
|
||||||
std::transform(
|
std::transform(phantom_nodes.front().begin(),
|
||||||
phantom_nodes.front().begin(),
|
phantom_nodes.front().end(),
|
||||||
phantom_nodes.front().end(),
|
waypoints.begin(),
|
||||||
waypoints.begin(),
|
[this, &fb_result](const PhantomNodeWithDistance &phantom_with_distance)
|
||||||
[this, &fb_result](const PhantomNodeWithDistance &phantom_with_distance) {
|
{
|
||||||
auto &phantom_node = phantom_with_distance.phantom_node;
|
auto &phantom_node = phantom_with_distance.phantom_node;
|
||||||
|
|
||||||
auto node_values = MakeNodes(phantom_node);
|
auto node_values = MakeNodes(phantom_node);
|
||||||
fbresult::Uint64Pair nodes{node_values.first, node_values.second};
|
fbresult::Uint64Pair nodes{node_values.first, node_values.second};
|
||||||
|
|
||||||
auto waypoint = MakeWaypoint(&fb_result, {phantom_node});
|
auto waypoint = MakeWaypoint(&fb_result, {phantom_node});
|
||||||
waypoint->add_nodes(&nodes);
|
waypoint->add_nodes(&nodes);
|
||||||
return waypoint->Finish();
|
return waypoint->Finish();
|
||||||
});
|
});
|
||||||
|
|
||||||
waypoints_vector = fb_result.CreateVector(waypoints);
|
waypoints_vector = fb_result.CreateVector(waypoints);
|
||||||
}
|
}
|
||||||
@@ -94,28 +94,29 @@ class NearestAPI final : public BaseAPI
|
|||||||
std::transform(phantom_nodes.front().begin(),
|
std::transform(phantom_nodes.front().begin(),
|
||||||
phantom_nodes.front().end(),
|
phantom_nodes.front().end(),
|
||||||
waypoints.values.begin(),
|
waypoints.values.begin(),
|
||||||
[this](const PhantomNodeWithDistance &phantom_with_distance) {
|
[this](const PhantomNodeWithDistance &phantom_with_distance)
|
||||||
|
{
|
||||||
auto &phantom_node = phantom_with_distance.phantom_node;
|
auto &phantom_node = phantom_with_distance.phantom_node;
|
||||||
auto waypoint = MakeWaypoint({phantom_node});
|
auto waypoint = MakeWaypoint({phantom_node});
|
||||||
|
|
||||||
util::json::Array nodes;
|
util::json::Array nodes;
|
||||||
|
nodes.values.reserve(2);
|
||||||
|
|
||||||
auto node_values = MakeNodes(phantom_node);
|
auto node_values = MakeNodes(phantom_node);
|
||||||
|
|
||||||
nodes.values.push_back(node_values.first);
|
nodes.values.emplace_back(node_values.first);
|
||||||
nodes.values.push_back(node_values.second);
|
nodes.values.emplace_back(node_values.second);
|
||||||
waypoint.values["nodes"] = std::move(nodes);
|
waypoint.values.emplace("nodes", std::move(nodes));
|
||||||
|
|
||||||
return waypoint;
|
return waypoint;
|
||||||
});
|
});
|
||||||
response.values["waypoints"] = std::move(waypoints);
|
response.values.emplace("waypoints", std::move(waypoints));
|
||||||
}
|
}
|
||||||
|
|
||||||
response.values["code"] = "Ok";
|
response.values.emplace("code", "Ok");
|
||||||
auto data_timestamp = facade.GetTimestamp();
|
auto data_timestamp = facade.GetTimestamp();
|
||||||
if (!data_timestamp.empty())
|
if (!data_timestamp.empty())
|
||||||
{
|
{
|
||||||
response.values["data_version"] = data_timestamp;
|
response.values.emplace("data_version", data_timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+118
-101
@@ -50,14 +50,14 @@ class RouteAPI : public BaseAPI
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(!raw_routes.routes.empty());
|
BOOST_ASSERT(!raw_routes.routes.empty());
|
||||||
|
|
||||||
if (response.is<flatbuffers::FlatBufferBuilder>())
|
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
|
||||||
{
|
{
|
||||||
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
|
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
|
||||||
MakeResponse(raw_routes, waypoint_candidates, fb_result);
|
MakeResponse(raw_routes, waypoint_candidates, fb_result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto &json_result = response.get<util::json::Object>();
|
auto &json_result = std::get<util::json::Object>(response);
|
||||||
MakeResponse(raw_routes, waypoint_candidates, json_result);
|
MakeResponse(raw_routes, waypoint_candidates, json_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,9 +77,10 @@ class RouteAPI : public BaseAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto response =
|
auto response =
|
||||||
MakeFBResponse(raw_routes, fb_result, [this, &waypoint_candidates, &fb_result]() {
|
MakeFBResponse(raw_routes,
|
||||||
return BaseAPI::MakeWaypoints(&fb_result, waypoint_candidates);
|
fb_result,
|
||||||
});
|
[this, &waypoint_candidates, &fb_result]()
|
||||||
|
{ return BaseAPI::MakeWaypoints(&fb_result, waypoint_candidates); });
|
||||||
|
|
||||||
if (!data_timestamp.empty())
|
if (!data_timestamp.empty())
|
||||||
{
|
{
|
||||||
@@ -109,14 +110,14 @@ class RouteAPI : public BaseAPI
|
|||||||
|
|
||||||
if (!parameters.skip_waypoints)
|
if (!parameters.skip_waypoints)
|
||||||
{
|
{
|
||||||
response.values["waypoints"] = BaseAPI::MakeWaypoints(waypoint_candidates);
|
response.values.emplace("waypoints", BaseAPI::MakeWaypoints(waypoint_candidates));
|
||||||
}
|
}
|
||||||
response.values["routes"] = std::move(jsRoutes);
|
response.values.emplace("routes", std::move(jsRoutes));
|
||||||
response.values["code"] = "Ok";
|
response.values.emplace("code", "Ok");
|
||||||
auto data_timestamp = facade.GetTimestamp();
|
auto data_timestamp = facade.GetTimestamp();
|
||||||
if (!data_timestamp.empty())
|
if (!data_timestamp.empty())
|
||||||
{
|
{
|
||||||
response.values["data_version"] = data_timestamp;
|
response.values.emplace("data_version", data_timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,8 +158,8 @@ class RouteAPI : public BaseAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ForwardIter>
|
template <typename ForwardIter>
|
||||||
mapbox::util::variant<flatbuffers::Offset<flatbuffers::String>,
|
std::variant<flatbuffers::Offset<flatbuffers::String>,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>>
|
flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>>
|
||||||
MakeGeometry(flatbuffers::FlatBufferBuilder &builder, ForwardIter begin, ForwardIter end) const
|
MakeGeometry(flatbuffers::FlatBufferBuilder &builder, ForwardIter begin, ForwardIter end) const
|
||||||
{
|
{
|
||||||
if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
|
if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
|
||||||
@@ -171,10 +172,15 @@ class RouteAPI : public BaseAPI
|
|||||||
}
|
}
|
||||||
std::vector<fbresult::Position> coordinates;
|
std::vector<fbresult::Position> coordinates;
|
||||||
coordinates.resize(std::distance(begin, end));
|
coordinates.resize(std::distance(begin, end));
|
||||||
std::transform(begin, end, coordinates.begin(), [](const Coordinate &c) {
|
std::transform(begin,
|
||||||
return fbresult::Position{static_cast<float>(util::toFloating(c.lon).__value),
|
end,
|
||||||
static_cast<float>(util::toFloating(c.lat).__value)};
|
coordinates.begin(),
|
||||||
});
|
[](const Coordinate &c)
|
||||||
|
{
|
||||||
|
return fbresult::Position{
|
||||||
|
static_cast<float>(util::toFloating(c.lon).__value),
|
||||||
|
static_cast<float>(util::toFloating(c.lat).__value)};
|
||||||
|
});
|
||||||
return builder.CreateVectorOfStructs(coordinates);
|
return builder.CreateVectorOfStructs(coordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,8 +340,8 @@ class RouteAPI : public BaseAPI
|
|||||||
unpacked_path_segments,
|
unpacked_path_segments,
|
||||||
source_traversed_in_reverse,
|
source_traversed_in_reverse,
|
||||||
target_traversed_in_reverse);
|
target_traversed_in_reverse);
|
||||||
std::vector<guidance::RouteLeg> legs = legs_info.first;
|
std::vector<guidance::RouteLeg> &legs = legs_info.first;
|
||||||
std::vector<guidance::LegGeometry> leg_geometries = legs_info.second;
|
std::vector<guidance::LegGeometry> &leg_geometries = legs_info.second;
|
||||||
auto route = guidance::assembleRoute(legs);
|
auto route = guidance::assembleRoute(legs);
|
||||||
|
|
||||||
// Fill legs
|
// Fill legs
|
||||||
@@ -354,9 +360,8 @@ class RouteAPI : public BaseAPI
|
|||||||
std::transform(leg.steps.begin(),
|
std::transform(leg.steps.begin(),
|
||||||
leg.steps.end(),
|
leg.steps.end(),
|
||||||
legSteps.begin(),
|
legSteps.begin(),
|
||||||
[this, &fb_result, &leg_geometry](auto &step) {
|
[this, &fb_result, &leg_geometry](auto &step)
|
||||||
return this->MakeFBStep(fb_result, leg_geometry, step);
|
{ return this->MakeFBStep(fb_result, leg_geometry, step); });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
auto steps_vector = fb_result.CreateVector(legSteps);
|
auto steps_vector = fb_result.CreateVector(legSteps);
|
||||||
|
|
||||||
@@ -403,8 +408,8 @@ class RouteAPI : public BaseAPI
|
|||||||
|
|
||||||
// Fill geometry
|
// Fill geometry
|
||||||
auto overview = MakeOverview(leg_geometries);
|
auto overview = MakeOverview(leg_geometries);
|
||||||
mapbox::util::variant<flatbuffers::Offset<flatbuffers::String>,
|
std::variant<flatbuffers::Offset<flatbuffers::String>,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>>
|
flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>>
|
||||||
geometry;
|
geometry;
|
||||||
if (overview)
|
if (overview)
|
||||||
{
|
{
|
||||||
@@ -421,8 +426,7 @@ class RouteAPI : public BaseAPI
|
|||||||
routeObject.add_legs(legs_vector);
|
routeObject.add_legs(legs_vector);
|
||||||
if (overview)
|
if (overview)
|
||||||
{
|
{
|
||||||
mapbox::util::apply_visitor(GeometryVisitor<fbresult::RouteObjectBuilder>(routeObject),
|
std::visit(GeometryVisitor<fbresult::RouteObjectBuilder>(routeObject), geometry);
|
||||||
geometry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return routeObject.Finish();
|
return routeObject.Finish();
|
||||||
@@ -438,58 +442,58 @@ class RouteAPI : public BaseAPI
|
|||||||
if (requested_annotations & RouteParameters::AnnotationsType::Speed)
|
if (requested_annotations & RouteParameters::AnnotationsType::Speed)
|
||||||
{
|
{
|
||||||
double prev_speed = 0;
|
double prev_speed = 0;
|
||||||
speed =
|
speed = GetAnnotations<float>(
|
||||||
GetAnnotations<float>(fb_result,
|
fb_result,
|
||||||
leg_geometry,
|
leg_geometry,
|
||||||
[&prev_speed](const guidance::LegGeometry::Annotation &anno) {
|
[&prev_speed](const guidance::LegGeometry::Annotation &anno)
|
||||||
if (anno.duration < std::numeric_limits<float>::min())
|
{
|
||||||
{
|
if (anno.duration < std::numeric_limits<float>::min())
|
||||||
return prev_speed;
|
{
|
||||||
}
|
return prev_speed;
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
auto speed =
|
{
|
||||||
round(anno.distance / anno.duration * 10.) / 10.;
|
auto speed = std::round(anno.distance / anno.duration * 10.) / 10.;
|
||||||
prev_speed = speed;
|
prev_speed = speed;
|
||||||
return util::json::clamp_float(speed);
|
return util::json::clamp_float(speed);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> duration;
|
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> duration;
|
||||||
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
|
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
|
||||||
{
|
{
|
||||||
duration = GetAnnotations<uint32_t>(
|
duration = GetAnnotations<uint32_t>(fb_result,
|
||||||
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
leg_geometry,
|
||||||
return anno.duration;
|
[](const guidance::LegGeometry::Annotation &anno)
|
||||||
});
|
{ return anno.duration; });
|
||||||
}
|
}
|
||||||
|
|
||||||
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> distance;
|
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> distance;
|
||||||
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
|
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
|
||||||
{
|
{
|
||||||
distance = GetAnnotations<uint32_t>(
|
distance = GetAnnotations<uint32_t>(fb_result,
|
||||||
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
leg_geometry,
|
||||||
return anno.distance;
|
[](const guidance::LegGeometry::Annotation &anno)
|
||||||
});
|
{ return anno.distance; });
|
||||||
}
|
}
|
||||||
|
|
||||||
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> weight;
|
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> weight;
|
||||||
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
|
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
|
||||||
{
|
{
|
||||||
weight = GetAnnotations<uint32_t>(
|
weight = GetAnnotations<uint32_t>(fb_result,
|
||||||
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
leg_geometry,
|
||||||
return anno.weight;
|
[](const guidance::LegGeometry::Annotation &anno)
|
||||||
});
|
{ return anno.weight; });
|
||||||
}
|
}
|
||||||
|
|
||||||
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> datasources;
|
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> datasources;
|
||||||
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
|
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
|
||||||
{
|
{
|
||||||
datasources = GetAnnotations<uint32_t>(
|
datasources = GetAnnotations<uint32_t>(fb_result,
|
||||||
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
leg_geometry,
|
||||||
return anno.datasource;
|
[](const guidance::LegGeometry::Annotation &anno)
|
||||||
});
|
{ return anno.datasource; });
|
||||||
}
|
}
|
||||||
std::vector<uint32_t> nodes;
|
std::vector<uint32_t> nodes;
|
||||||
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
|
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
|
||||||
@@ -639,7 +643,7 @@ class RouteAPI : public BaseAPI
|
|||||||
stepBuilder.add_rotary_pronunciation(rotary_pronunciation_string);
|
stepBuilder.add_rotary_pronunciation(rotary_pronunciation_string);
|
||||||
stepBuilder.add_intersections(intersections_vector);
|
stepBuilder.add_intersections(intersections_vector);
|
||||||
stepBuilder.add_maneuver(maneuver_buffer);
|
stepBuilder.add_maneuver(maneuver_buffer);
|
||||||
mapbox::util::apply_visitor(GeometryVisitor<fbresult::StepBuilder>(stepBuilder), geometry);
|
std::visit(GeometryVisitor<fbresult::StepBuilder>(stepBuilder), geometry);
|
||||||
return stepBuilder.Finish();
|
return stepBuilder.Finish();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -653,7 +657,8 @@ class RouteAPI : public BaseAPI
|
|||||||
step.intersections.begin(),
|
step.intersections.begin(),
|
||||||
step.intersections.end(),
|
step.intersections.end(),
|
||||||
intersections.begin(),
|
intersections.begin(),
|
||||||
[&fb_result, this](const guidance::IntermediateIntersection &intersection) {
|
[&fb_result, this](const guidance::IntermediateIntersection &intersection)
|
||||||
|
{
|
||||||
std::vector<flatbuffers::Offset<fbresult::Lane>> lanes;
|
std::vector<flatbuffers::Offset<fbresult::Lane>> lanes;
|
||||||
if (json::detail::hasValidLanes(intersection))
|
if (json::detail::hasValidLanes(intersection))
|
||||||
{
|
{
|
||||||
@@ -681,11 +686,11 @@ class RouteAPI : public BaseAPI
|
|||||||
auto bearings_vector = fb_result.CreateVector(intersection.bearings);
|
auto bearings_vector = fb_result.CreateVector(intersection.bearings);
|
||||||
std::vector<flatbuffers::Offset<flatbuffers::String>> classes;
|
std::vector<flatbuffers::Offset<flatbuffers::String>> classes;
|
||||||
classes.resize(intersection.classes.size());
|
classes.resize(intersection.classes.size());
|
||||||
std::transform(
|
std::transform(intersection.classes.begin(),
|
||||||
intersection.classes.begin(),
|
intersection.classes.end(),
|
||||||
intersection.classes.end(),
|
classes.begin(),
|
||||||
classes.begin(),
|
[&fb_result](const std::string &cls)
|
||||||
[&fb_result](const std::string &cls) { return fb_result.CreateString(cls); });
|
{ return fb_result.CreateString(cls); });
|
||||||
auto classes_vector = fb_result.CreateVector(classes);
|
auto classes_vector = fb_result.CreateVector(classes);
|
||||||
auto entry_vector = fb_result.CreateVector(intersection.entry);
|
auto entry_vector = fb_result.CreateVector(intersection.entry);
|
||||||
|
|
||||||
@@ -711,8 +716,8 @@ class RouteAPI : public BaseAPI
|
|||||||
unpacked_path_segments,
|
unpacked_path_segments,
|
||||||
source_traversed_in_reverse,
|
source_traversed_in_reverse,
|
||||||
target_traversed_in_reverse);
|
target_traversed_in_reverse);
|
||||||
std::vector<guidance::RouteLeg> legs = legs_info.first;
|
std::vector<guidance::RouteLeg> &legs = legs_info.first;
|
||||||
std::vector<guidance::LegGeometry> leg_geometries = legs_info.second;
|
std::vector<guidance::LegGeometry> &leg_geometries = legs_info.second;
|
||||||
|
|
||||||
auto route = guidance::assembleRoute(legs);
|
auto route = guidance::assembleRoute(legs);
|
||||||
boost::optional<util::json::Value> json_overview =
|
boost::optional<util::json::Value> json_overview =
|
||||||
@@ -720,9 +725,10 @@ class RouteAPI : public BaseAPI
|
|||||||
|
|
||||||
std::vector<util::json::Value> step_geometries;
|
std::vector<util::json::Value> step_geometries;
|
||||||
const auto total_step_count =
|
const auto total_step_count =
|
||||||
std::accumulate(legs.begin(), legs.end(), 0, [](const auto &v, const auto &leg) {
|
std::accumulate(legs.begin(),
|
||||||
return v + leg.steps.size();
|
legs.end(),
|
||||||
});
|
0,
|
||||||
|
[](const auto &v, const auto &leg) { return v + leg.steps.size(); });
|
||||||
step_geometries.reserve(total_step_count);
|
step_geometries.reserve(total_step_count);
|
||||||
|
|
||||||
for (const auto idx : util::irange<std::size_t>(0UL, legs.size()))
|
for (const auto idx : util::irange<std::size_t>(0UL, legs.size()))
|
||||||
@@ -733,7 +739,8 @@ class RouteAPI : public BaseAPI
|
|||||||
legs[idx].steps.begin(),
|
legs[idx].steps.begin(),
|
||||||
legs[idx].steps.end(),
|
legs[idx].steps.end(),
|
||||||
std::back_inserter(step_geometries),
|
std::back_inserter(step_geometries),
|
||||||
[this, &leg_geometry](const guidance::RouteStep &step) {
|
[this, &leg_geometry](const guidance::RouteStep &step)
|
||||||
|
{
|
||||||
if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
|
if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
|
||||||
{
|
{
|
||||||
return static_cast<util::json::Value>(json::makePolyline<100000>(
|
return static_cast<util::json::Value>(json::makePolyline<100000>(
|
||||||
@@ -777,47 +784,57 @@ class RouteAPI : public BaseAPI
|
|||||||
if (requested_annotations & RouteParameters::AnnotationsType::Speed)
|
if (requested_annotations & RouteParameters::AnnotationsType::Speed)
|
||||||
{
|
{
|
||||||
double prev_speed = 0;
|
double prev_speed = 0;
|
||||||
annotation.values["speed"] = GetAnnotations(
|
annotation.values.emplace(
|
||||||
leg_geometry, [&prev_speed](const guidance::LegGeometry::Annotation &anno) {
|
"speed",
|
||||||
if (anno.duration < std::numeric_limits<double>::min())
|
GetAnnotations(leg_geometry,
|
||||||
{
|
[&prev_speed](const guidance::LegGeometry::Annotation &anno)
|
||||||
return prev_speed;
|
{
|
||||||
}
|
if (anno.duration < std::numeric_limits<double>::min())
|
||||||
else
|
{
|
||||||
{
|
return prev_speed;
|
||||||
auto speed = std::round(anno.distance / anno.duration * 10.) / 10.;
|
}
|
||||||
prev_speed = speed;
|
else
|
||||||
return util::json::clamp_float(speed);
|
{
|
||||||
}
|
auto speed =
|
||||||
});
|
std::round(anno.distance / anno.duration * 10.) /
|
||||||
|
10.;
|
||||||
|
prev_speed = speed;
|
||||||
|
return util::json::clamp_float(speed);
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
|
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
|
||||||
{
|
{
|
||||||
annotation.values["duration"] = GetAnnotations(
|
annotation.values.emplace(
|
||||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
"duration",
|
||||||
return anno.duration;
|
GetAnnotations(leg_geometry,
|
||||||
});
|
[](const guidance::LegGeometry::Annotation &anno)
|
||||||
|
{ return anno.duration; }));
|
||||||
}
|
}
|
||||||
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
|
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
|
||||||
{
|
{
|
||||||
annotation.values["distance"] = GetAnnotations(
|
annotation.values.emplace(
|
||||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
"distance",
|
||||||
return anno.distance;
|
GetAnnotations(leg_geometry,
|
||||||
});
|
[](const guidance::LegGeometry::Annotation &anno)
|
||||||
|
{ return anno.distance; }));
|
||||||
}
|
}
|
||||||
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
|
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
|
||||||
{
|
{
|
||||||
annotation.values["weight"] = GetAnnotations(
|
annotation.values.emplace(
|
||||||
leg_geometry,
|
"weight",
|
||||||
[](const guidance::LegGeometry::Annotation &anno) { return anno.weight; });
|
GetAnnotations(leg_geometry,
|
||||||
|
[](const guidance::LegGeometry::Annotation &anno)
|
||||||
|
{ return anno.weight; }));
|
||||||
}
|
}
|
||||||
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
|
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
|
||||||
{
|
{
|
||||||
annotation.values["datasources"] = GetAnnotations(
|
annotation.values.emplace(
|
||||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
"datasources",
|
||||||
return anno.datasource;
|
GetAnnotations(leg_geometry,
|
||||||
});
|
[](const guidance::LegGeometry::Annotation &anno)
|
||||||
|
{ return anno.datasource; }));
|
||||||
}
|
}
|
||||||
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
|
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
|
||||||
{
|
{
|
||||||
@@ -828,7 +845,7 @@ class RouteAPI : public BaseAPI
|
|||||||
nodes.values.push_back(
|
nodes.values.push_back(
|
||||||
static_cast<std::uint64_t>(facade.GetOSMNodeIDOfNode(node_id)));
|
static_cast<std::uint64_t>(facade.GetOSMNodeIDOfNode(node_id)));
|
||||||
}
|
}
|
||||||
annotation.values["nodes"] = std::move(nodes);
|
annotation.values.emplace("nodes", std::move(nodes));
|
||||||
}
|
}
|
||||||
// Add any supporting metadata, if needed
|
// Add any supporting metadata, if needed
|
||||||
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
|
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
|
||||||
@@ -844,8 +861,8 @@ class RouteAPI : public BaseAPI
|
|||||||
break;
|
break;
|
||||||
datasource_names.values.push_back(std::string(facade.GetDatasourceName(i)));
|
datasource_names.values.push_back(std::string(facade.GetDatasourceName(i)));
|
||||||
}
|
}
|
||||||
metadata.values["datasource_names"] = datasource_names;
|
metadata.values.emplace("datasource_names", datasource_names);
|
||||||
annotation.values["metadata"] = metadata;
|
annotation.values.emplace("metadata", metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
annotations.push_back(std::move(annotation));
|
annotations.push_back(std::move(annotation));
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ struct RouteParameters : public BaseParameters
|
|||||||
const GeometriesType geometries_,
|
const GeometriesType geometries_,
|
||||||
const OverviewType overview_,
|
const OverviewType overview_,
|
||||||
const boost::optional<bool> continue_straight_,
|
const boost::optional<bool> continue_straight_,
|
||||||
Args &&... args_)
|
Args &&...args_)
|
||||||
// Once we perfectly-forward `args` (see #2990) this constructor can delegate to the one
|
// Once we perfectly-forward `args` (see #2990) this constructor can delegate to the one
|
||||||
// below.
|
// below.
|
||||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||||
@@ -101,7 +101,7 @@ struct RouteParameters : public BaseParameters
|
|||||||
const GeometriesType geometries_,
|
const GeometriesType geometries_,
|
||||||
const OverviewType overview_,
|
const OverviewType overview_,
|
||||||
const boost::optional<bool> continue_straight_,
|
const boost::optional<bool> continue_straight_,
|
||||||
Args &&... args_)
|
Args &&...args_)
|
||||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||||
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
|
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
|
||||||
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
|
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
|
||||||
@@ -119,7 +119,7 @@ struct RouteParameters : public BaseParameters
|
|||||||
const GeometriesType geometries_,
|
const GeometriesType geometries_,
|
||||||
const OverviewType overview_,
|
const OverviewType overview_,
|
||||||
const boost::optional<bool> continue_straight_,
|
const boost::optional<bool> continue_straight_,
|
||||||
Args &&... args_)
|
Args &&...args_)
|
||||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||||
number_of_alternatives{alternatives_ ? 1u : 0u},
|
number_of_alternatives{alternatives_ ? 1u : 0u},
|
||||||
annotations{annotations_ != AnnotationsType::None}, annotations_type{annotations_},
|
annotations{annotations_ != AnnotationsType::None}, annotations_type{annotations_},
|
||||||
@@ -137,7 +137,7 @@ struct RouteParameters : public BaseParameters
|
|||||||
const OverviewType overview_,
|
const OverviewType overview_,
|
||||||
const boost::optional<bool> continue_straight_,
|
const boost::optional<bool> continue_straight_,
|
||||||
std::vector<std::size_t> waypoints_,
|
std::vector<std::size_t> waypoints_,
|
||||||
const Args &&... args_)
|
const Args &&...args_)
|
||||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||||
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
|
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
|
||||||
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
|
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
|
||||||
@@ -155,7 +155,7 @@ struct RouteParameters : public BaseParameters
|
|||||||
const OverviewType overview_,
|
const OverviewType overview_,
|
||||||
const boost::optional<bool> continue_straight_,
|
const boost::optional<bool> continue_straight_,
|
||||||
std::vector<std::size_t> waypoints_,
|
std::vector<std::size_t> waypoints_,
|
||||||
Args &&... args_)
|
Args &&...args_)
|
||||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||||
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_ !=
|
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_ !=
|
||||||
AnnotationsType::None},
|
AnnotationsType::None},
|
||||||
@@ -180,9 +180,9 @@ struct RouteParameters : public BaseParameters
|
|||||||
const auto coordinates_ok = coordinates.size() >= 2;
|
const auto coordinates_ok = coordinates.size() >= 2;
|
||||||
const auto base_params_ok = BaseParameters::IsValid();
|
const auto base_params_ok = BaseParameters::IsValid();
|
||||||
const auto valid_waypoints =
|
const auto valid_waypoints =
|
||||||
std::all_of(waypoints.begin(), waypoints.end(), [this](const auto &w) {
|
std::all_of(waypoints.begin(),
|
||||||
return w < coordinates.size();
|
waypoints.end(),
|
||||||
});
|
[this](const auto &w) { return w < coordinates.size(); });
|
||||||
return coordinates_ok && base_params_ok && valid_waypoints;
|
return coordinates_ok && base_params_ok && valid_waypoints;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,14 +50,14 @@ class TableAPI final : public BaseAPI
|
|||||||
const std::vector<TableCellRef> &fallback_speed_cells,
|
const std::vector<TableCellRef> &fallback_speed_cells,
|
||||||
osrm::engine::api::ResultT &response) const
|
osrm::engine::api::ResultT &response) const
|
||||||
{
|
{
|
||||||
if (response.is<flatbuffers::FlatBufferBuilder>())
|
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
|
||||||
{
|
{
|
||||||
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
|
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
|
||||||
MakeResponse(tables, candidates, fallback_speed_cells, fb_result);
|
MakeResponse(tables, candidates, fallback_speed_cells, fb_result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto &json_result = response.get<util::json::Object>();
|
auto &json_result = std::get<util::json::Object>(response);
|
||||||
MakeResponse(tables, candidates, fallback_speed_cells, json_result);
|
MakeResponse(tables, candidates, fallback_speed_cells, json_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,7 +179,7 @@ class TableAPI final : public BaseAPI
|
|||||||
{
|
{
|
||||||
if (!parameters.skip_waypoints)
|
if (!parameters.skip_waypoints)
|
||||||
{
|
{
|
||||||
response.values["sources"] = MakeWaypoints(candidates);
|
response.values.emplace("sources", MakeWaypoints(candidates));
|
||||||
}
|
}
|
||||||
number_of_sources = candidates.size();
|
number_of_sources = candidates.size();
|
||||||
}
|
}
|
||||||
@@ -187,7 +187,7 @@ class TableAPI final : public BaseAPI
|
|||||||
{
|
{
|
||||||
if (!parameters.skip_waypoints)
|
if (!parameters.skip_waypoints)
|
||||||
{
|
{
|
||||||
response.values["sources"] = MakeWaypoints(candidates, parameters.sources);
|
response.values.emplace("sources", MakeWaypoints(candidates, parameters.sources));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ class TableAPI final : public BaseAPI
|
|||||||
{
|
{
|
||||||
if (!parameters.skip_waypoints)
|
if (!parameters.skip_waypoints)
|
||||||
{
|
{
|
||||||
response.values["destinations"] = MakeWaypoints(candidates);
|
response.values.emplace("destinations", MakeWaypoints(candidates));
|
||||||
}
|
}
|
||||||
number_of_destinations = candidates.size();
|
number_of_destinations = candidates.size();
|
||||||
}
|
}
|
||||||
@@ -203,34 +203,37 @@ class TableAPI final : public BaseAPI
|
|||||||
{
|
{
|
||||||
if (!parameters.skip_waypoints)
|
if (!parameters.skip_waypoints)
|
||||||
{
|
{
|
||||||
response.values["destinations"] =
|
response.values.emplace("destinations",
|
||||||
MakeWaypoints(candidates, parameters.destinations);
|
MakeWaypoints(candidates, parameters.destinations));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.annotations & TableParameters::AnnotationsType::Duration)
|
if (parameters.annotations & TableParameters::AnnotationsType::Duration)
|
||||||
{
|
{
|
||||||
response.values["durations"] =
|
response.values.emplace(
|
||||||
MakeDurationTable(tables.first, number_of_sources, number_of_destinations);
|
"durations",
|
||||||
|
MakeDurationTable(tables.first, number_of_sources, number_of_destinations));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.annotations & TableParameters::AnnotationsType::Distance)
|
if (parameters.annotations & TableParameters::AnnotationsType::Distance)
|
||||||
{
|
{
|
||||||
response.values["distances"] =
|
response.values.emplace(
|
||||||
MakeDistanceTable(tables.second, number_of_sources, number_of_destinations);
|
"distances",
|
||||||
|
MakeDistanceTable(tables.second, number_of_sources, number_of_destinations));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.fallback_speed != from_alias<double>(INVALID_FALLBACK_SPEED) &&
|
if (parameters.fallback_speed != from_alias<double>(INVALID_FALLBACK_SPEED) &&
|
||||||
parameters.fallback_speed > 0)
|
parameters.fallback_speed > 0)
|
||||||
{
|
{
|
||||||
response.values["fallback_speed_cells"] = MakeEstimatesTable(fallback_speed_cells);
|
response.values.emplace("fallback_speed_cells",
|
||||||
|
MakeEstimatesTable(fallback_speed_cells));
|
||||||
}
|
}
|
||||||
|
|
||||||
response.values["code"] = "Ok";
|
response.values.emplace("code", "Ok");
|
||||||
auto data_timestamp = facade.GetTimestamp();
|
auto data_timestamp = facade.GetTimestamp();
|
||||||
if (!data_timestamp.empty())
|
if (!data_timestamp.empty())
|
||||||
{
|
{
|
||||||
response.values["data_version"] = data_timestamp;
|
response.values.emplace("data_version", data_timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,9 +248,8 @@ class TableAPI final : public BaseAPI
|
|||||||
|
|
||||||
boost::range::transform(candidates,
|
boost::range::transform(candidates,
|
||||||
std::back_inserter(waypoints),
|
std::back_inserter(waypoints),
|
||||||
[this, &builder](const PhantomNodeCandidates &candidates) {
|
[this, &builder](const PhantomNodeCandidates &candidates)
|
||||||
return BaseAPI::MakeWaypoint(&builder, candidates)->Finish();
|
{ return BaseAPI::MakeWaypoint(&builder, candidates)->Finish(); });
|
||||||
});
|
|
||||||
return builder.CreateVector(waypoints);
|
return builder.CreateVector(waypoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +263,8 @@ class TableAPI final : public BaseAPI
|
|||||||
boost::range::transform(
|
boost::range::transform(
|
||||||
indices,
|
indices,
|
||||||
std::back_inserter(waypoints),
|
std::back_inserter(waypoints),
|
||||||
[this, &builder, &candidates](const std::size_t idx) {
|
[this, &builder, &candidates](const std::size_t idx)
|
||||||
|
{
|
||||||
BOOST_ASSERT(idx < candidates.size());
|
BOOST_ASSERT(idx < candidates.size());
|
||||||
return BaseAPI::MakeWaypoint(&builder, candidates[idx])->Finish();
|
return BaseAPI::MakeWaypoint(&builder, candidates[idx])->Finish();
|
||||||
});
|
});
|
||||||
@@ -274,14 +277,17 @@ class TableAPI final : public BaseAPI
|
|||||||
{
|
{
|
||||||
std::vector<float> distance_table;
|
std::vector<float> distance_table;
|
||||||
distance_table.resize(values.size());
|
distance_table.resize(values.size());
|
||||||
std::transform(
|
std::transform(values.begin(),
|
||||||
values.begin(), values.end(), distance_table.begin(), [](const EdgeDuration duration) {
|
values.end(),
|
||||||
if (duration == MAXIMAL_EDGE_DURATION)
|
distance_table.begin(),
|
||||||
{
|
[](const EdgeDuration duration)
|
||||||
return 0.;
|
{
|
||||||
}
|
if (duration == MAXIMAL_EDGE_DURATION)
|
||||||
return from_alias<double>(duration) / 10.;
|
{
|
||||||
});
|
return 0.;
|
||||||
|
}
|
||||||
|
return from_alias<double>(duration) / 10.;
|
||||||
|
});
|
||||||
return builder.CreateVector(distance_table);
|
return builder.CreateVector(distance_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,14 +297,17 @@ class TableAPI final : public BaseAPI
|
|||||||
{
|
{
|
||||||
std::vector<float> duration_table;
|
std::vector<float> duration_table;
|
||||||
duration_table.resize(values.size());
|
duration_table.resize(values.size());
|
||||||
std::transform(
|
std::transform(values.begin(),
|
||||||
values.begin(), values.end(), duration_table.begin(), [](const EdgeDistance distance) {
|
values.end(),
|
||||||
if (distance == INVALID_EDGE_DISTANCE)
|
duration_table.begin(),
|
||||||
{
|
[](const EdgeDistance distance)
|
||||||
return 0.;
|
{
|
||||||
}
|
if (distance == INVALID_EDGE_DISTANCE)
|
||||||
return std::round(from_alias<double>(distance) * 10) / 10.;
|
{
|
||||||
});
|
return 0.;
|
||||||
|
}
|
||||||
|
return std::round(from_alias<double>(distance) * 10) / 10.;
|
||||||
|
});
|
||||||
return builder.CreateVector(duration_table);
|
return builder.CreateVector(duration_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,11 +317,13 @@ class TableAPI final : public BaseAPI
|
|||||||
{
|
{
|
||||||
std::vector<uint32_t> fb_table;
|
std::vector<uint32_t> fb_table;
|
||||||
fb_table.reserve(fallback_speed_cells.size());
|
fb_table.reserve(fallback_speed_cells.size());
|
||||||
std::for_each(
|
std::for_each(fallback_speed_cells.begin(),
|
||||||
fallback_speed_cells.begin(), fallback_speed_cells.end(), [&](const auto &cell) {
|
fallback_speed_cells.end(),
|
||||||
fb_table.push_back(cell.row);
|
[&](const auto &cell)
|
||||||
fb_table.push_back(cell.column);
|
{
|
||||||
});
|
fb_table.push_back(cell.row);
|
||||||
|
fb_table.push_back(cell.column);
|
||||||
|
});
|
||||||
return builder.CreateVector(fb_table);
|
return builder.CreateVector(fb_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,9 +336,8 @@ class TableAPI final : public BaseAPI
|
|||||||
|
|
||||||
boost::range::transform(candidates,
|
boost::range::transform(candidates,
|
||||||
std::back_inserter(json_waypoints.values),
|
std::back_inserter(json_waypoints.values),
|
||||||
[this](const PhantomNodeCandidates &candidates) {
|
[this](const PhantomNodeCandidates &candidates)
|
||||||
return BaseAPI::MakeWaypoint(candidates);
|
{ return BaseAPI::MakeWaypoint(candidates); });
|
||||||
});
|
|
||||||
return json_waypoints;
|
return json_waypoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +348,8 @@ class TableAPI final : public BaseAPI
|
|||||||
json_waypoints.values.reserve(indices.size());
|
json_waypoints.values.reserve(indices.size());
|
||||||
boost::range::transform(indices,
|
boost::range::transform(indices,
|
||||||
std::back_inserter(json_waypoints.values),
|
std::back_inserter(json_waypoints.values),
|
||||||
[this, &candidates](const std::size_t idx) {
|
[this, &candidates](const std::size_t idx)
|
||||||
|
{
|
||||||
BOOST_ASSERT(idx < candidates.size());
|
BOOST_ASSERT(idx < candidates.size());
|
||||||
return BaseAPI::MakeWaypoint(candidates[idx]);
|
return BaseAPI::MakeWaypoint(candidates[idx]);
|
||||||
});
|
});
|
||||||
@@ -359,7 +370,8 @@ class TableAPI final : public BaseAPI
|
|||||||
std::transform(row_begin_iterator,
|
std::transform(row_begin_iterator,
|
||||||
row_end_iterator,
|
row_end_iterator,
|
||||||
json_row.values.begin(),
|
json_row.values.begin(),
|
||||||
[](const EdgeDuration duration) {
|
[](const EdgeDuration duration)
|
||||||
|
{
|
||||||
if (duration == MAXIMAL_EDGE_DURATION)
|
if (duration == MAXIMAL_EDGE_DURATION)
|
||||||
{
|
{
|
||||||
return util::json::Value(util::json::Null());
|
return util::json::Value(util::json::Null());
|
||||||
@@ -368,7 +380,8 @@ class TableAPI final : public BaseAPI
|
|||||||
return util::json::Value(
|
return util::json::Value(
|
||||||
util::json::Number(from_alias<double>(duration) / 10.));
|
util::json::Number(from_alias<double>(duration) / 10.));
|
||||||
});
|
});
|
||||||
json_table.values.push_back(std::move(json_row));
|
|
||||||
|
json_table.values.push_back(util::json::Value{json_row});
|
||||||
}
|
}
|
||||||
return json_table;
|
return json_table;
|
||||||
}
|
}
|
||||||
@@ -387,7 +400,8 @@ class TableAPI final : public BaseAPI
|
|||||||
std::transform(row_begin_iterator,
|
std::transform(row_begin_iterator,
|
||||||
row_end_iterator,
|
row_end_iterator,
|
||||||
json_row.values.begin(),
|
json_row.values.begin(),
|
||||||
[](const EdgeDistance distance) {
|
[](const EdgeDistance distance)
|
||||||
|
{
|
||||||
if (distance == INVALID_EDGE_DISTANCE)
|
if (distance == INVALID_EDGE_DISTANCE)
|
||||||
{
|
{
|
||||||
return util::json::Value(util::json::Null());
|
return util::json::Value(util::json::Null());
|
||||||
@@ -396,7 +410,7 @@ class TableAPI final : public BaseAPI
|
|||||||
return util::json::Value(util::json::Number(
|
return util::json::Value(util::json::Number(
|
||||||
std::round(from_alias<double>(distance) * 10) / 10.));
|
std::round(from_alias<double>(distance) * 10) / 10.));
|
||||||
});
|
});
|
||||||
json_table.values.push_back(std::move(json_row));
|
json_table.values.push_back(util::json::Value{json_row});
|
||||||
}
|
}
|
||||||
return json_table;
|
return json_table;
|
||||||
}
|
}
|
||||||
@@ -406,11 +420,16 @@ class TableAPI final : public BaseAPI
|
|||||||
{
|
{
|
||||||
util::json::Array json_table;
|
util::json::Array json_table;
|
||||||
std::for_each(
|
std::for_each(
|
||||||
fallback_speed_cells.begin(), fallback_speed_cells.end(), [&](const auto &cell) {
|
fallback_speed_cells.begin(),
|
||||||
|
fallback_speed_cells.end(),
|
||||||
|
[&](const auto &cell)
|
||||||
|
{
|
||||||
util::json::Array row;
|
util::json::Array row;
|
||||||
row.values.push_back(util::json::Number(cell.row));
|
util::json::Value jCellRow{util::json::Number(static_cast<double>(cell.row))};
|
||||||
row.values.push_back(util::json::Number(cell.column));
|
util::json::Value jCellColumn{util::json::Number(static_cast<double>(cell.column))};
|
||||||
json_table.values.push_back(std::move(row));
|
row.values.push_back(jCellRow);
|
||||||
|
row.values.push_back(jCellColumn);
|
||||||
|
json_table.values.push_back(util::json::Value{row});
|
||||||
});
|
});
|
||||||
return json_table;
|
return json_table;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ struct TableParameters : public BaseParameters
|
|||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
TableParameters(std::vector<std::size_t> sources_,
|
TableParameters(std::vector<std::size_t> sources_,
|
||||||
std::vector<std::size_t> destinations_,
|
std::vector<std::size_t> destinations_,
|
||||||
Args &&... args_)
|
Args &&...args_)
|
||||||
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
||||||
destinations{std::move(destinations_)}
|
destinations{std::move(destinations_)}
|
||||||
{
|
{
|
||||||
@@ -91,7 +91,7 @@ struct TableParameters : public BaseParameters
|
|||||||
TableParameters(std::vector<std::size_t> sources_,
|
TableParameters(std::vector<std::size_t> sources_,
|
||||||
std::vector<std::size_t> destinations_,
|
std::vector<std::size_t> destinations_,
|
||||||
const AnnotationsType annotations_,
|
const AnnotationsType annotations_,
|
||||||
Args &&... args_)
|
Args &&...args_)
|
||||||
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
||||||
destinations{std::move(destinations_)}, annotations{annotations_}
|
destinations{std::move(destinations_)}, annotations{annotations_}
|
||||||
{
|
{
|
||||||
@@ -104,7 +104,7 @@ struct TableParameters : public BaseParameters
|
|||||||
double fallback_speed_,
|
double fallback_speed_,
|
||||||
FallbackCoordinateType fallback_coordinate_type_,
|
FallbackCoordinateType fallback_coordinate_type_,
|
||||||
double scale_factor_,
|
double scale_factor_,
|
||||||
Args &&... args_)
|
Args &&...args_)
|
||||||
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
||||||
destinations{std::move(destinations_)}, fallback_speed{fallback_speed_},
|
destinations{std::move(destinations_)}, fallback_speed{fallback_speed_},
|
||||||
fallback_coordinate_type{fallback_coordinate_type_}, annotations{annotations_},
|
fallback_coordinate_type{fallback_coordinate_type_}, annotations{annotations_},
|
||||||
|
|||||||
@@ -27,14 +27,14 @@ class TripAPI final : public RouteAPI
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(sub_trips.size() == sub_routes.size());
|
BOOST_ASSERT(sub_trips.size() == sub_routes.size());
|
||||||
|
|
||||||
if (response.is<flatbuffers::FlatBufferBuilder>())
|
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
|
||||||
{
|
{
|
||||||
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
|
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
|
||||||
MakeResponse(sub_trips, sub_routes, candidates, fb_result);
|
MakeResponse(sub_trips, sub_routes, candidates, fb_result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto &json_result = response.get<util::json::Object>();
|
auto &json_result = std::get<util::json::Object>(response);
|
||||||
MakeResponse(sub_trips, sub_routes, candidates, json_result);
|
MakeResponse(sub_trips, sub_routes, candidates, json_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,10 +50,10 @@ class TripAPI final : public RouteAPI
|
|||||||
data_version_string = fb_result.CreateString(data_timestamp);
|
data_version_string = fb_result.CreateString(data_timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto response =
|
auto response = MakeFBResponse(sub_routes,
|
||||||
MakeFBResponse(sub_routes, fb_result, [this, &fb_result, &sub_trips, &candidates]() {
|
fb_result,
|
||||||
return MakeWaypoints(fb_result, sub_trips, candidates);
|
[this, &fb_result, &sub_trips, &candidates]()
|
||||||
});
|
{ return MakeWaypoints(fb_result, sub_trips, candidates); });
|
||||||
|
|
||||||
if (!data_timestamp.empty())
|
if (!data_timestamp.empty())
|
||||||
{
|
{
|
||||||
@@ -79,14 +79,14 @@ class TripAPI final : public RouteAPI
|
|||||||
}
|
}
|
||||||
if (!parameters.skip_waypoints)
|
if (!parameters.skip_waypoints)
|
||||||
{
|
{
|
||||||
response.values["waypoints"] = MakeWaypoints(sub_trips, candidates);
|
response.values.emplace("waypoints", MakeWaypoints(sub_trips, candidates));
|
||||||
}
|
}
|
||||||
response.values["trips"] = std::move(routes);
|
response.values.emplace("trips", std::move(routes));
|
||||||
response.values["code"] = "Ok";
|
response.values.emplace("code", "Ok");
|
||||||
auto data_timestamp = facade.GetTimestamp();
|
auto data_timestamp = facade.GetTimestamp();
|
||||||
if (!data_timestamp.empty())
|
if (!data_timestamp.empty())
|
||||||
{
|
{
|
||||||
response.values["data_version"] = data_timestamp;
|
response.values.emplace("data_version", data_timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,8 +151,8 @@ class TripAPI final : public RouteAPI
|
|||||||
BOOST_ASSERT(!trip_index.NotUsed());
|
BOOST_ASSERT(!trip_index.NotUsed());
|
||||||
|
|
||||||
auto waypoint = BaseAPI::MakeWaypoint(candidates[input_index]);
|
auto waypoint = BaseAPI::MakeWaypoint(candidates[input_index]);
|
||||||
waypoint.values["trips_index"] = trip_index.sub_trip_index;
|
waypoint.values.emplace("trips_index", trip_index.sub_trip_index);
|
||||||
waypoint.values["waypoint_index"] = trip_index.point_index;
|
waypoint.values.emplace("waypoint_index", trip_index.point_index);
|
||||||
waypoints.values.push_back(std::move(waypoint));
|
waypoints.values.push_back(std::move(waypoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ struct TripParameters : public RouteParameters
|
|||||||
TripParameters(SourceType source_,
|
TripParameters(SourceType source_,
|
||||||
DestinationType destination_,
|
DestinationType destination_,
|
||||||
bool roundtrip_,
|
bool roundtrip_,
|
||||||
Args &&... args_)
|
Args &&...args_)
|
||||||
: RouteParameters{std::forward<Args>(args_)...}, source{source_},
|
: RouteParameters{std::forward<Args>(args_)...}, source{source_},
|
||||||
destination{destination_}, roundtrip{roundtrip_}
|
destination{destination_}, roundtrip{roundtrip_}
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ namespace osrm::engine
|
|||||||
enum class Approach : std::uint8_t
|
enum class Approach : std::uint8_t
|
||||||
{
|
{
|
||||||
CURB = 0,
|
CURB = 0,
|
||||||
UNRESTRICTED = 1
|
UNRESTRICTED = 1,
|
||||||
|
OPPOSITE = 2
|
||||||
|
|
||||||
};
|
};
|
||||||
} // namespace osrm::engine
|
} // namespace osrm::engine
|
||||||
|
|||||||
+16
-11
@@ -47,24 +47,29 @@ namespace engine
|
|||||||
// Encodes a chunk of memory to Base64.
|
// Encodes a chunk of memory to Base64.
|
||||||
inline std::string encodeBase64(const unsigned char *first, std::size_t size)
|
inline std::string encodeBase64(const unsigned char *first, std::size_t size)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> bytes{first, first + size};
|
BOOST_ASSERT(size > 0);
|
||||||
BOOST_ASSERT(!bytes.empty());
|
|
||||||
|
|
||||||
std::size_t bytes_to_pad{0};
|
std::string encoded;
|
||||||
|
encoded.reserve(((size + 2) / 3) * 4);
|
||||||
|
|
||||||
while (bytes.size() % 3 != 0)
|
auto padding = (3 - size % 3) % 3;
|
||||||
|
|
||||||
|
BOOST_ASSERT(padding == 0 || padding == 1 || padding == 2);
|
||||||
|
|
||||||
|
for (auto itr = detail::Base64FromBinary(first); itr != detail::Base64FromBinary(first + size);
|
||||||
|
++itr)
|
||||||
{
|
{
|
||||||
bytes_to_pad += 1;
|
encoded.push_back(*itr);
|
||||||
bytes.push_back(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(bytes_to_pad == 0 || bytes_to_pad == 1 || bytes_to_pad == 2);
|
for (size_t index = 0; index < padding; ++index)
|
||||||
BOOST_ASSERT_MSG(0 == bytes.size() % 3, "base64 input data size is not a multiple of 3");
|
{
|
||||||
|
encoded.push_back('=');
|
||||||
|
}
|
||||||
|
|
||||||
std::string encoded{detail::Base64FromBinary{bytes.data()},
|
BOOST_ASSERT(encoded.size() == (size + 2) / 3 * 4);
|
||||||
detail::Base64FromBinary{bytes.data() + (bytes.size() - bytes_to_pad)}};
|
|
||||||
|
|
||||||
return encoded.append(bytes_to_pad, '=');
|
return encoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
// C++11 standard 3.9.1/1: Plain char, signed char, and unsigned char are three distinct types
|
// C++11 standard 3.9.1/1: Plain char, signed char, and unsigned char are three distinct types
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ template <> class AlgorithmDataFacade<CH>
|
|||||||
|
|
||||||
virtual EdgeID FindSmallestEdge(const NodeID edge_based_node_from,
|
virtual EdgeID FindSmallestEdge(const NodeID edge_based_node_from,
|
||||||
const NodeID edge_based_node_to,
|
const NodeID edge_based_node_to,
|
||||||
const std::function<bool(EdgeData)> filter) const = 0;
|
const std::function<bool(const EdgeData &)> &filter) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> class AlgorithmDataFacade<MLD>
|
template <> class AlgorithmDataFacade<MLD>
|
||||||
|
|||||||
@@ -130,9 +130,10 @@ class ContiguousInternalMemoryAlgorithmDataFacade<CH> : public datafacade::Algor
|
|||||||
edge_based_node_from, edge_based_node_to, result);
|
edge_based_node_from, edge_based_node_to, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeID FindSmallestEdge(const NodeID edge_based_node_from,
|
EdgeID
|
||||||
const NodeID edge_based_node_to,
|
FindSmallestEdge(const NodeID edge_based_node_from,
|
||||||
std::function<bool(EdgeData)> filter) const override final
|
const NodeID edge_based_node_to,
|
||||||
|
const std::function<bool(const EdgeData &)> &filter) const override final
|
||||||
{
|
{
|
||||||
return m_query_graph.FindSmallestEdge(edge_based_node_from, edge_based_node_to, filter);
|
return m_query_graph.FindSmallestEdge(edge_based_node_from, edge_based_node_to, filter);
|
||||||
}
|
}
|
||||||
@@ -176,7 +177,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
|
|
||||||
SharedRTree m_static_rtree;
|
SharedRTree m_static_rtree;
|
||||||
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
|
std::unique_ptr<SharedGeospatialQuery> m_geospatial_query;
|
||||||
boost::filesystem::path file_index_path;
|
std::filesystem::path file_index_path;
|
||||||
|
|
||||||
std::optional<extractor::IntersectionBearingsView> intersection_bearings_view;
|
std::optional<extractor::IntersectionBearingsView> intersection_bearings_view;
|
||||||
|
|
||||||
@@ -375,7 +376,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
BOOST_ASSERT(m_geospatial_query.get());
|
BOOST_ASSERT(m_geospatial_query.get());
|
||||||
|
|
||||||
return m_geospatial_query->NearestPhantomNodes(
|
return m_geospatial_query->NearestPhantomNodes(
|
||||||
input_coordinate, approach, boost::none, max_distance, bearing, use_all_edges);
|
input_coordinate, approach, max_distance, bearing, use_all_edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PhantomNodeWithDistance>
|
std::vector<PhantomNodeWithDistance>
|
||||||
@@ -440,9 +441,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
{
|
{
|
||||||
auto indexes = extractor::getClassIndexes(class_data);
|
auto indexes = extractor::getClassIndexes(class_data);
|
||||||
std::vector<std::string> classes(indexes.size());
|
std::vector<std::string> classes(indexes.size());
|
||||||
std::transform(indexes.begin(), indexes.end(), classes.begin(), [this](const auto index) {
|
std::transform(indexes.begin(),
|
||||||
return m_profile_properties->GetClassName(index);
|
indexes.end(),
|
||||||
});
|
classes.begin(),
|
||||||
|
[this](const auto index)
|
||||||
|
{ return m_profile_properties->GetClassName(index); });
|
||||||
|
|
||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
@@ -600,15 +603,19 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
auto found_range = std::equal_range(
|
auto found_range = std::equal_range(
|
||||||
m_maneuver_overrides.begin(), m_maneuver_overrides.end(), edge_based_node_id, Comp{});
|
m_maneuver_overrides.begin(), m_maneuver_overrides.end(), edge_based_node_id, Comp{});
|
||||||
|
|
||||||
std::for_each(found_range.first, found_range.second, [&](const auto &override) {
|
std::for_each(found_range.first,
|
||||||
std::vector<NodeID> sequence(
|
found_range.second,
|
||||||
m_maneuver_override_node_sequences.begin() + override.node_sequence_offset_begin,
|
[&](const auto &override)
|
||||||
m_maneuver_override_node_sequences.begin() + override.node_sequence_offset_end);
|
{
|
||||||
results.push_back(extractor::ManeuverOverride{std::move(sequence),
|
std::vector<NodeID> sequence(m_maneuver_override_node_sequences.begin() +
|
||||||
override.instruction_node,
|
override.node_sequence_offset_begin,
|
||||||
override.override_type,
|
m_maneuver_override_node_sequences.begin() +
|
||||||
override.direction});
|
override.node_sequence_offset_end);
|
||||||
});
|
results.push_back(extractor::ManeuverOverride{std::move(sequence),
|
||||||
|
override.instruction_node,
|
||||||
|
override.override_type,
|
||||||
|
override.direction});
|
||||||
|
});
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,8 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "storage/storage_config.hpp"
|
#include "storage/storage_config.hpp"
|
||||||
#include "osrm/datasets.hpp"
|
#include "osrm/datasets.hpp"
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <filesystem>
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -54,14 +53,10 @@ namespace osrm::engine
|
|||||||
*
|
*
|
||||||
* In addition, shared memory can be used for datasets loaded with osrm-datastore.
|
* In addition, shared memory can be used for datasets loaded with osrm-datastore.
|
||||||
*
|
*
|
||||||
* You can chose between three algorithms:
|
* You can chose between two algorithms:
|
||||||
* - Algorithm::CH
|
* - Algorithm::CH
|
||||||
* Contraction Hierarchies, extremely fast queries but slow pre-processing. The default right
|
* Contraction Hierarchies, extremely fast queries but slow pre-processing. The default right
|
||||||
* now.
|
* now.
|
||||||
* - Algorithm::CoreCH
|
|
||||||
* Deprecated, to be removed in v6.0
|
|
||||||
* Contraction Hierachies with partial contraction for faster pre-processing but slower
|
|
||||||
* queries.
|
|
||||||
* - Algorithm::MLD
|
* - Algorithm::MLD
|
||||||
* Multi Level Dijkstra, moderately fast in both pre-processing and query.
|
* Multi Level Dijkstra, moderately fast in both pre-processing and query.
|
||||||
*
|
*
|
||||||
@@ -74,7 +69,6 @@ struct EngineConfig final
|
|||||||
enum class Algorithm
|
enum class Algorithm
|
||||||
{
|
{
|
||||||
CH,
|
CH,
|
||||||
CoreCH, // Deprecated, will be removed in v6.0
|
|
||||||
MLD
|
MLD
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -88,7 +82,7 @@ struct EngineConfig final
|
|||||||
boost::optional<double> default_radius = -1.0;
|
boost::optional<double> default_radius = -1.0;
|
||||||
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
|
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
|
||||||
bool use_shared_memory = true;
|
bool use_shared_memory = true;
|
||||||
boost::filesystem::path memory_file;
|
std::filesystem::path memory_file;
|
||||||
bool use_mmap = true;
|
bool use_mmap = true;
|
||||||
Algorithm algorithm = Algorithm::CH;
|
Algorithm algorithm = Algorithm::CH;
|
||||||
std::vector<storage::FeatureDataset> disable_feature_dataset;
|
std::vector<storage::FeatureDataset> disable_feature_dataset;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include "osrm/coordinate.hpp"
|
#include "osrm/coordinate.hpp"
|
||||||
|
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
@@ -47,12 +49,42 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
return rtree.SearchInBox(bbox);
|
return rtree.SearchInBox(bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PhantomNodeWithDistance>
|
||||||
|
NearestPhantomNodes(const util::Coordinate input_coordinate,
|
||||||
|
const Approach approach,
|
||||||
|
const double max_distance,
|
||||||
|
const boost::optional<Bearing> bearing_with_range,
|
||||||
|
const boost::optional<bool> use_all_edges) const
|
||||||
|
{
|
||||||
|
auto results = rtree.SearchInRange(
|
||||||
|
input_coordinate,
|
||||||
|
max_distance,
|
||||||
|
[this, approach, &input_coordinate, &bearing_with_range, &use_all_edges, max_distance](
|
||||||
|
const CandidateSegment &segment)
|
||||||
|
{
|
||||||
|
auto invalidDistance =
|
||||||
|
CheckSegmentDistance(input_coordinate, segment, max_distance);
|
||||||
|
if (invalidDistance)
|
||||||
|
{
|
||||||
|
return std::make_pair(false, false);
|
||||||
|
}
|
||||||
|
auto valid = CheckSegmentExclude(segment) &&
|
||||||
|
CheckApproach(input_coordinate, segment, approach) &&
|
||||||
|
(use_all_edges ? HasValidEdge(segment, *use_all_edges)
|
||||||
|
: HasValidEdge(segment)) &&
|
||||||
|
(bearing_with_range ? CheckSegmentBearing(segment, *bearing_with_range)
|
||||||
|
: std::make_pair(true, true));
|
||||||
|
return valid;
|
||||||
|
});
|
||||||
|
return MakePhantomNodes(input_coordinate, results);
|
||||||
|
}
|
||||||
|
|
||||||
// Returns max_results nearest PhantomNodes that are valid within the provided parameters.
|
// Returns max_results nearest PhantomNodes that are valid within the provided parameters.
|
||||||
// Does not filter by small/big component!
|
// Does not filter by small/big component!
|
||||||
std::vector<PhantomNodeWithDistance>
|
std::vector<PhantomNodeWithDistance>
|
||||||
NearestPhantomNodes(const util::Coordinate input_coordinate,
|
NearestPhantomNodes(const util::Coordinate input_coordinate,
|
||||||
const Approach approach,
|
const Approach approach,
|
||||||
const boost::optional<size_t> max_results,
|
const size_t max_results,
|
||||||
const boost::optional<double> max_distance,
|
const boost::optional<double> max_distance,
|
||||||
const boost::optional<Bearing> bearing_with_range,
|
const boost::optional<Bearing> bearing_with_range,
|
||||||
const boost::optional<bool> use_all_edges) const
|
const boost::optional<bool> use_all_edges) const
|
||||||
@@ -60,7 +92,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
auto results = rtree.Nearest(
|
auto results = rtree.Nearest(
|
||||||
input_coordinate,
|
input_coordinate,
|
||||||
[this, approach, &input_coordinate, &bearing_with_range, &use_all_edges](
|
[this, approach, &input_coordinate, &bearing_with_range, &use_all_edges](
|
||||||
const CandidateSegment &segment) {
|
const CandidateSegment &segment)
|
||||||
|
{
|
||||||
auto valid = CheckSegmentExclude(segment) &&
|
auto valid = CheckSegmentExclude(segment) &&
|
||||||
CheckApproach(input_coordinate, segment, approach) &&
|
CheckApproach(input_coordinate, segment, approach) &&
|
||||||
(use_all_edges ? HasValidEdge(segment, *use_all_edges)
|
(use_all_edges ? HasValidEdge(segment, *use_all_edges)
|
||||||
@@ -69,9 +102,10 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
: std::make_pair(true, true));
|
: std::make_pair(true, true));
|
||||||
return valid;
|
return valid;
|
||||||
},
|
},
|
||||||
[this, &max_distance, &max_results, input_coordinate](const std::size_t num_results,
|
[this, &max_distance, max_results, input_coordinate](const std::size_t num_results,
|
||||||
const CandidateSegment &segment) {
|
const CandidateSegment &segment)
|
||||||
return (max_results && num_results >= *max_results) ||
|
{
|
||||||
|
return (num_results >= max_results) ||
|
||||||
(max_distance && max_distance != -1.0 &&
|
(max_distance && max_distance != -1.0 &&
|
||||||
CheckSegmentDistance(input_coordinate, segment, *max_distance));
|
CheckSegmentDistance(input_coordinate, segment, *max_distance));
|
||||||
});
|
});
|
||||||
@@ -107,7 +141,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
&big_component_coord,
|
&big_component_coord,
|
||||||
&big_component_distance,
|
&big_component_distance,
|
||||||
&use_all_edges,
|
&use_all_edges,
|
||||||
&bearing_with_range](const CandidateSegment &segment) {
|
&bearing_with_range](const CandidateSegment &segment)
|
||||||
|
{
|
||||||
auto is_big_component = !IsTinyComponent(segment);
|
auto is_big_component = !IsTinyComponent(segment);
|
||||||
auto not_nearest =
|
auto not_nearest =
|
||||||
has_nearest && segment.fixed_projected_coordinate != nearest_coord;
|
has_nearest && segment.fixed_projected_coordinate != nearest_coord;
|
||||||
@@ -159,7 +194,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
return use_candidate;
|
return use_candidate;
|
||||||
},
|
},
|
||||||
[this, &has_big_component, &max_distance, input_coordinate, &big_component_distance](
|
[this, &has_big_component, &max_distance, input_coordinate, &big_component_distance](
|
||||||
const std::size_t /*num_results*/, const CandidateSegment &segment) {
|
const std::size_t /*num_results*/, const CandidateSegment &segment)
|
||||||
|
{
|
||||||
auto distance = GetSegmentDistance(input_coordinate, segment);
|
auto distance = GetSegmentDistance(input_coordinate, segment);
|
||||||
auto further_than_big_component = distance > big_component_distance;
|
auto further_than_big_component = distance > big_component_distance;
|
||||||
auto no_more_candidates = has_big_component && further_than_big_component;
|
auto no_more_candidates = has_big_component && further_than_big_component;
|
||||||
@@ -190,13 +226,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
PhantomNodeCandidates nearest_phantoms;
|
PhantomNodeCandidates nearest_phantoms;
|
||||||
PhantomNodeCandidates big_component_phantoms;
|
PhantomNodeCandidates big_component_phantoms;
|
||||||
|
|
||||||
const auto add_to_candidates = [this, &input_coordinate](PhantomNodeCandidates &candidates,
|
const auto add_to_candidates =
|
||||||
const EdgeData data) {
|
[this, &input_coordinate](PhantomNodeCandidates &candidates, const EdgeData data)
|
||||||
|
{
|
||||||
auto candidate_it =
|
auto candidate_it =
|
||||||
std::find_if(candidates.begin(), candidates.end(), [&](const PhantomNode &node) {
|
std::find_if(candidates.begin(),
|
||||||
return data.forward_segment_id.id == node.forward_segment_id.id &&
|
candidates.end(),
|
||||||
data.reverse_segment_id.id == node.reverse_segment_id.id;
|
[&](const PhantomNode &node)
|
||||||
});
|
{
|
||||||
|
return data.forward_segment_id.id == node.forward_segment_id.id &&
|
||||||
|
data.reverse_segment_id.id == node.reverse_segment_id.id;
|
||||||
|
});
|
||||||
if (candidate_it == candidates.end())
|
if (candidate_it == candidates.end())
|
||||||
{
|
{
|
||||||
// First candidate from this segment
|
// First candidate from this segment
|
||||||
@@ -259,17 +299,20 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::for_each(results.begin(), results.end(), [&](const CandidateSegment &segment) {
|
std::for_each(results.begin(),
|
||||||
if (segment.fixed_projected_coordinate == nearest_coord)
|
results.end(),
|
||||||
{
|
[&](const CandidateSegment &segment)
|
||||||
add_to_candidates(nearest_phantoms, segment.data);
|
{
|
||||||
}
|
if (segment.fixed_projected_coordinate == nearest_coord)
|
||||||
else
|
{
|
||||||
{
|
add_to_candidates(nearest_phantoms, segment.data);
|
||||||
// Can only be from a big component for the alternative candidates
|
}
|
||||||
add_to_candidates(big_component_phantoms, segment.data);
|
else
|
||||||
}
|
{
|
||||||
});
|
// Can only be from a big component for the alternative candidates
|
||||||
|
add_to_candidates(big_component_phantoms, segment.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
return std::make_pair(std::move(nearest_phantoms), std::move(big_component_phantoms));
|
return std::make_pair(std::move(nearest_phantoms), std::move(big_component_phantoms));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,9 +324,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
std::transform(results.begin(),
|
std::transform(results.begin(),
|
||||||
results.end(),
|
results.end(),
|
||||||
distance_and_phantoms.begin(),
|
distance_and_phantoms.begin(),
|
||||||
[this, &input_coordinate](const CandidateSegment &segment) {
|
[this, &input_coordinate](const CandidateSegment &segment)
|
||||||
return MakePhantomNode(input_coordinate, segment.data);
|
{ return MakePhantomNode(input_coordinate, segment.data); });
|
||||||
});
|
|
||||||
return distance_and_phantoms;
|
return distance_and_phantoms;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,9 +442,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check phantom node segments validity
|
// check phantom node segments validity
|
||||||
auto areSegmentsValid = [](auto first, auto last) -> bool {
|
auto areSegmentsValid = [](auto first, auto last) -> bool
|
||||||
return std::find(first, last, INVALID_SEGMENT_WEIGHT) == last;
|
{ return std::find(first, last, INVALID_SEGMENT_WEIGHT) == last; };
|
||||||
};
|
|
||||||
bool is_forward_valid_source =
|
bool is_forward_valid_source =
|
||||||
areSegmentsValid(forward_weights.begin(), forward_weights.end());
|
areSegmentsValid(forward_weights.begin(), forward_weights.end());
|
||||||
bool is_forward_valid_target = areSegmentsValid(
|
bool is_forward_valid_target = areSegmentsValid(
|
||||||
@@ -558,7 +599,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
{
|
{
|
||||||
bool isOnewaySegment =
|
bool isOnewaySegment =
|
||||||
!(segment.data.forward_segment_id.enabled && segment.data.reverse_segment_id.enabled);
|
!(segment.data.forward_segment_id.enabled && segment.data.reverse_segment_id.enabled);
|
||||||
if (!isOnewaySegment && approach == Approach::CURB)
|
if (!isOnewaySegment && (approach == Approach::CURB || approach == Approach::OPPOSITE))
|
||||||
{
|
{
|
||||||
// Check the counter clockwise
|
// Check the counter clockwise
|
||||||
//
|
//
|
||||||
@@ -573,6 +614,9 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
if (datafacade.IsLeftHandDriving(segment.data.forward_segment_id.id))
|
if (datafacade.IsLeftHandDriving(segment.data.forward_segment_id.id))
|
||||||
input_coordinate_is_at_right = !input_coordinate_is_at_right;
|
input_coordinate_is_at_right = !input_coordinate_is_at_right;
|
||||||
|
|
||||||
|
if (approach == Approach::OPPOSITE)
|
||||||
|
input_coordinate_is_at_right = !input_coordinate_is_at_right;
|
||||||
|
|
||||||
return std::make_pair(input_coordinate_is_at_right, (!input_coordinate_is_at_right));
|
return std::make_pair(input_coordinate_is_at_right, (!input_coordinate_is_at_right));
|
||||||
}
|
}
|
||||||
return std::make_pair(true, true);
|
return std::make_pair(true, true);
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
|
|||||||
const bool target_traversed_in_reverse)
|
const bool target_traversed_in_reverse)
|
||||||
{
|
{
|
||||||
// merges segments with same name id
|
// merges segments with same name id
|
||||||
const auto collapse_segments = [](std::vector<NamedSegment> &segments) {
|
const auto collapse_segments = [](std::vector<NamedSegment> &segments)
|
||||||
|
{
|
||||||
auto out = segments.begin();
|
auto out = segments.begin();
|
||||||
auto end = segments.end();
|
auto end = segments.end();
|
||||||
|
|
||||||
@@ -75,7 +76,8 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
|
|||||||
std::transform(route_data.begin(),
|
std::transform(route_data.begin(),
|
||||||
route_data.end(),
|
route_data.end(),
|
||||||
segments.begin(),
|
segments.begin(),
|
||||||
[&index, &facade](const PathData &point) {
|
[&index, &facade](const PathData &point)
|
||||||
|
{
|
||||||
return NamedSegment{point.duration_until_turn,
|
return NamedSegment{point.duration_until_turn,
|
||||||
index++,
|
index++,
|
||||||
facade.GetNameIndex(point.from_edge_based_node)};
|
facade.GetNameIndex(point.from_edge_based_node)};
|
||||||
@@ -87,33 +89,37 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
|
|||||||
if (target_duration > EdgeDuration{1})
|
if (target_duration > EdgeDuration{1})
|
||||||
segments.push_back({target_duration, index++, facade.GetNameIndex(target_node_id)});
|
segments.push_back({target_duration, index++, facade.GetNameIndex(target_node_id)});
|
||||||
// this makes sure that the segment with the lowest position comes first
|
// this makes sure that the segment with the lowest position comes first
|
||||||
std::sort(
|
std::sort(segments.begin(),
|
||||||
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
|
segments.end(),
|
||||||
return lhs.name_id < rhs.name_id ||
|
[](const NamedSegment &lhs, const NamedSegment &rhs)
|
||||||
(lhs.name_id == rhs.name_id && lhs.position < rhs.position);
|
{
|
||||||
});
|
return lhs.name_id < rhs.name_id ||
|
||||||
|
(lhs.name_id == rhs.name_id && lhs.position < rhs.position);
|
||||||
|
});
|
||||||
auto new_end = collapse_segments(segments);
|
auto new_end = collapse_segments(segments);
|
||||||
segments.resize(new_end - segments.begin());
|
segments.resize(new_end - segments.begin());
|
||||||
|
|
||||||
// Filter out segments with an empty name (name_id == 0)
|
// Filter out segments with an empty name (name_id == 0)
|
||||||
new_end = std::remove_if(segments.begin(), segments.end(), [](const NamedSegment &segment) {
|
new_end = std::remove_if(segments.begin(),
|
||||||
return segment.name_id == 0;
|
segments.end(),
|
||||||
});
|
[](const NamedSegment &segment) { return segment.name_id == 0; });
|
||||||
segments.resize(new_end - segments.begin());
|
segments.resize(new_end - segments.begin());
|
||||||
|
|
||||||
// sort descending
|
// sort descending
|
||||||
std::sort(
|
std::sort(segments.begin(),
|
||||||
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
|
segments.end(),
|
||||||
return lhs.duration > rhs.duration ||
|
[](const NamedSegment &lhs, const NamedSegment &rhs)
|
||||||
(lhs.duration == rhs.duration && lhs.position < rhs.position);
|
{
|
||||||
});
|
return lhs.duration > rhs.duration ||
|
||||||
|
(lhs.duration == rhs.duration && lhs.position < rhs.position);
|
||||||
|
});
|
||||||
|
|
||||||
// make sure the segments are sorted by position
|
// make sure the segments are sorted by position
|
||||||
segments.resize(std::min(segments.size(), SegmentNumber));
|
segments.resize(std::min(segments.size(), SegmentNumber));
|
||||||
std::sort(
|
std::sort(segments.begin(),
|
||||||
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
|
segments.end(),
|
||||||
return lhs.position < rhs.position;
|
[](const NamedSegment &lhs, const NamedSegment &rhs)
|
||||||
});
|
{ return lhs.position < rhs.position; });
|
||||||
|
|
||||||
std::array<std::uint32_t, SegmentNumber> summary;
|
std::array<std::uint32_t, SegmentNumber> summary;
|
||||||
std::fill(summary.begin(), summary.end(), EMPTY_NAMEID);
|
std::fill(summary.begin(), summary.end(), EMPTY_NAMEID);
|
||||||
@@ -138,7 +144,8 @@ inline std::string assembleSummary(const datafacade::BaseDataFacade &facade,
|
|||||||
|
|
||||||
// transform a name_id into a string containing either the name, or -if the name is empty-
|
// transform a name_id into a string containing either the name, or -if the name is empty-
|
||||||
// the reference.
|
// the reference.
|
||||||
const auto name_id_to_string = [&](const NameID name_id) {
|
const auto name_id_to_string = [&](const NameID name_id)
|
||||||
|
{
|
||||||
const auto name = facade.GetNameForID(name_id);
|
const auto name = facade.GetNameForID(name_id);
|
||||||
if (!name.empty())
|
if (!name.empty())
|
||||||
return std::string(name);
|
return std::string(name);
|
||||||
@@ -178,14 +185,16 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
|||||||
const auto target_weight =
|
const auto target_weight =
|
||||||
(target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight);
|
(target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight);
|
||||||
|
|
||||||
auto duration = std::accumulate(
|
auto duration = std::accumulate(route_data.begin(),
|
||||||
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
|
route_data.end(),
|
||||||
return sum + from_alias<double>(data.duration_until_turn);
|
0,
|
||||||
});
|
[](const double sum, const PathData &data)
|
||||||
auto weight = std::accumulate(
|
{ return sum + from_alias<double>(data.duration_until_turn); });
|
||||||
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
|
auto weight = std::accumulate(route_data.begin(),
|
||||||
return sum + from_alias<double>(data.weight_until_turn);
|
route_data.end(),
|
||||||
});
|
0,
|
||||||
|
[](const double sum, const PathData &data)
|
||||||
|
{ return sum + from_alias<double>(data.weight_until_turn); });
|
||||||
|
|
||||||
// s
|
// s
|
||||||
// |
|
// |
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ bool basicCollapsePreconditions(const RouteStepIterator first,
|
|||||||
|
|
||||||
// Staggered intersection are very short zig-zags of a few meters.
|
// Staggered intersection are very short zig-zags of a few meters.
|
||||||
// We do not want to announce these short left-rights or right-lefts:
|
// We do not want to announce these short left-rights or right-lefts:
|
||||||
//
|
//
|
||||||
// * -> b a -> *
|
// * -> b a -> *
|
||||||
// | or | becomes a -> b
|
// | or | becomes a -> b
|
||||||
// a -> * * -> b
|
// a -> * * -> b
|
||||||
@@ -26,7 +26,7 @@ bool isStaggeredIntersection(const RouteStepIterator step_prior_to_intersection,
|
|||||||
|
|
||||||
// Two two turns following close after another, we can announce them as a U-Turn if both end up
|
// Two two turns following close after another, we can announce them as a U-Turn if both end up
|
||||||
// involving the same (segregated) road.
|
// involving the same (segregated) road.
|
||||||
//
|
//
|
||||||
// b < - y
|
// b < - y
|
||||||
// | will be represented by at x, turn around instead of turn left at x, turn left at y
|
// | will be represented by at x, turn around instead of turn left at x, turn left at y
|
||||||
// a - > x
|
// a - > x
|
||||||
@@ -42,11 +42,11 @@ bool isNameOszillation(const RouteStepIterator step_prior_to_intersection,
|
|||||||
|
|
||||||
// Sometimes, segments names don't match the perceived turns. We try to detect these additional
|
// Sometimes, segments names don't match the perceived turns. We try to detect these additional
|
||||||
// name changes and issue a combined turn.
|
// name changes and issue a combined turn.
|
||||||
//
|
//
|
||||||
// | e |
|
// | e |
|
||||||
// a - b - c
|
// a - b - c
|
||||||
// d
|
// d
|
||||||
//
|
//
|
||||||
// can have `a-b` as one name, `b-c-d` as a second. At `b` we would issue a new name, even though
|
// can have `a-b` as one name, `b-c-d` as a second. At `b` we would issue a new name, even though
|
||||||
// the road turns right after. The offset would only be there due to the broad road at `e`
|
// the road turns right after. The offset would only be there due to the broad road at `e`
|
||||||
bool maneuverPreceededByNameChange(const RouteStepIterator step_prior_to_intersection,
|
bool maneuverPreceededByNameChange(const RouteStepIterator step_prior_to_intersection,
|
||||||
@@ -73,11 +73,11 @@ bool doubleChoiceless(const RouteStepIterator step_entering_intersection,
|
|||||||
|
|
||||||
// Due to obvious detection, sometimes we can have straight turns followed by a different turn right
|
// Due to obvious detection, sometimes we can have straight turns followed by a different turn right
|
||||||
// next to each other. We combine both turns into one, if the second turn is without choice
|
// next to each other. We combine both turns into one, if the second turn is without choice
|
||||||
//
|
//
|
||||||
// e
|
// e
|
||||||
// a - b - c
|
// a - b - c
|
||||||
// ' d
|
// ' d
|
||||||
//
|
//
|
||||||
// with a main road `abd`, the turn `continue straight` at `b` and `turn left at `c` will become a
|
// with a main road `abd`, the turn `continue straight` at `b` and `turn left at `c` will become a
|
||||||
// `turn left` at `b`
|
// `turn left` at `b`
|
||||||
bool straightTurnFollowedByChoiceless(const RouteStepIterator step_entering_intersection,
|
bool straightTurnFollowedByChoiceless(const RouteStepIterator step_entering_intersection,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#ifndef OSRM_ENGINE_GUIDANCE_COLLAPSE_HPP
|
#ifndef OSRM_ENGINE_GUIDANCE_COLLAPSE_HPP
|
||||||
|
|
||||||
#include "engine/guidance/route_step.hpp"
|
#include "engine/guidance/route_step.hpp"
|
||||||
#include "util/attributes.hpp"
|
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -12,16 +11,15 @@ namespace osrm::engine::guidance
|
|||||||
// Multiple possible reasons can result in unnecessary/confusing instructions
|
// Multiple possible reasons can result in unnecessary/confusing instructions
|
||||||
// Collapsing such turns into a single turn instruction, we give a clearer
|
// Collapsing such turns into a single turn instruction, we give a clearer
|
||||||
// set of instructions that is not cluttered by unnecessary turns/name changes.
|
// set of instructions that is not cluttered by unnecessary turns/name changes.
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] std::vector<RouteStep> collapseTurnInstructions(std::vector<RouteStep> steps);
|
||||||
std::vector<RouteStep> collapseTurnInstructions(std::vector<RouteStep> steps);
|
|
||||||
|
|
||||||
// Multiple possible reasons can result in unnecessary/confusing instructions
|
// Multiple possible reasons can result in unnecessary/confusing instructions
|
||||||
// A prime example would be a segregated intersection. Turning around at this
|
// A prime example would be a segregated intersection. Turning around at this
|
||||||
// intersection would result in two instructions to turn left.
|
// intersection would result in two instructions to turn left.
|
||||||
// Collapsing such turns into a single turn instruction, we give a clearer
|
// Collapsing such turns into a single turn instruction, we give a clearer
|
||||||
// set of instructions that is not cluttered by unnecessary turns/name changes.
|
// set of instructions that is not cluttered by unnecessary turns/name changes.
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] std::vector<RouteStep>
|
||||||
std::vector<RouteStep> collapseSegregatedTurnInstructions(std::vector<RouteStep> steps);
|
collapseSegregatedTurnInstructions(std::vector<RouteStep> steps);
|
||||||
|
|
||||||
// A combined turn is a set of two instructions that actually form a single turn, as far as we
|
// A combined turn is a set of two instructions that actually form a single turn, as far as we
|
||||||
// perceive it. A u-turn consisting of two left turns is one such example. But there are also lots
|
// perceive it. A u-turn consisting of two left turns is one such example. But there are also lots
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include "guidance/turn_instruction.hpp"
|
#include "guidance/turn_instruction.hpp"
|
||||||
#include "engine/guidance/route_step.hpp"
|
#include "engine/guidance/route_step.hpp"
|
||||||
#include "util/attributes.hpp"
|
|
||||||
#include "util/bearing.hpp"
|
#include "util/bearing.hpp"
|
||||||
#include "util/guidance/name_announcements.hpp"
|
#include "util/guidance/name_announcements.hpp"
|
||||||
|
|
||||||
@@ -122,9 +121,8 @@ inline bool haveSameMode(const RouteStep &first, const RouteStep &second, const
|
|||||||
// alias for readability
|
// alias for readability
|
||||||
inline bool haveSameName(const RouteStep &lhs, const RouteStep &rhs)
|
inline bool haveSameName(const RouteStep &lhs, const RouteStep &rhs)
|
||||||
{
|
{
|
||||||
const auto has_name_or_ref = [](auto const &step) {
|
const auto has_name_or_ref = [](auto const &step)
|
||||||
return !step.name.empty() || !step.ref.empty();
|
{ return !step.name.empty() || !step.ref.empty(); };
|
||||||
};
|
|
||||||
|
|
||||||
// make sure empty is not involved
|
// make sure empty is not involved
|
||||||
if (!has_name_or_ref(lhs) || !has_name_or_ref(rhs))
|
if (!has_name_or_ref(lhs) || !has_name_or_ref(rhs))
|
||||||
@@ -151,12 +149,14 @@ inline bool haveSameName(const RouteStep &lhs, const RouteStep &rhs)
|
|||||||
// alias for readability, both turn right | left
|
// alias for readability, both turn right | left
|
||||||
inline bool areSameSide(const RouteStep &lhs, const RouteStep &rhs)
|
inline bool areSameSide(const RouteStep &lhs, const RouteStep &rhs)
|
||||||
{
|
{
|
||||||
const auto is_left = [](const RouteStep &step) {
|
const auto is_left = [](const RouteStep &step)
|
||||||
|
{
|
||||||
return hasModifier(step, osrm::guidance::DirectionModifier::Straight) ||
|
return hasModifier(step, osrm::guidance::DirectionModifier::Straight) ||
|
||||||
hasLeftModifier(step.maneuver.instruction);
|
hasLeftModifier(step.maneuver.instruction);
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto is_right = [](const RouteStep &step) {
|
const auto is_right = [](const RouteStep &step)
|
||||||
|
{
|
||||||
return hasModifier(step, osrm::guidance::DirectionModifier::Straight) ||
|
return hasModifier(step, osrm::guidance::DirectionModifier::Straight) ||
|
||||||
hasRightModifier(step.maneuver.instruction);
|
hasRightModifier(step.maneuver.instruction);
|
||||||
};
|
};
|
||||||
@@ -165,8 +165,7 @@ inline bool areSameSide(const RouteStep &lhs, const RouteStep &rhs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// do this after invalidating any steps to compress the step array again
|
// do this after invalidating any steps to compress the step array again
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] inline std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> steps)
|
||||||
inline std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> steps)
|
|
||||||
{
|
{
|
||||||
// finally clean up the post-processed instructions.
|
// finally clean up the post-processed instructions.
|
||||||
// Remove all invalid instructions from the set of instructions.
|
// Remove all invalid instructions from the set of instructions.
|
||||||
@@ -174,7 +173,8 @@ inline std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> st
|
|||||||
// Two valid NO_TURNs exist in each leg in the form of Depart/Arrive
|
// Two valid NO_TURNs exist in each leg in the form of Depart/Arrive
|
||||||
|
|
||||||
// keep valid instructions
|
// keep valid instructions
|
||||||
const auto not_is_valid = [](const RouteStep &step) {
|
const auto not_is_valid = [](const RouteStep &step)
|
||||||
|
{
|
||||||
return step.maneuver.instruction == osrm::guidance::TurnInstruction::NO_TURN() &&
|
return step.maneuver.instruction == osrm::guidance::TurnInstruction::NO_TURN() &&
|
||||||
step.maneuver.waypoint_type == WaypointType::None;
|
step.maneuver.waypoint_type == WaypointType::None;
|
||||||
};
|
};
|
||||||
@@ -202,8 +202,8 @@ inline double totalTurnAngle(const RouteStep &entry_step, const RouteStep &exit_
|
|||||||
if (entry_step.geometry_begin > exit_step.geometry_begin)
|
if (entry_step.geometry_begin > exit_step.geometry_begin)
|
||||||
return totalTurnAngle(exit_step, entry_step);
|
return totalTurnAngle(exit_step, entry_step);
|
||||||
|
|
||||||
const auto exit_intersection = exit_step.intersections.front();
|
const auto &exit_intersection = exit_step.intersections.front();
|
||||||
const auto entry_intersection = entry_step.intersections.front();
|
const auto &entry_intersection = entry_step.intersections.front();
|
||||||
if ((exit_intersection.out >= exit_intersection.bearings.size()) ||
|
if ((exit_intersection.out >= exit_intersection.bearings.size()) ||
|
||||||
(entry_intersection.in >= entry_intersection.bearings.size()))
|
(entry_intersection.in >= entry_intersection.bearings.size()))
|
||||||
return entry_intersection.bearings[entry_intersection.out];
|
return entry_intersection.bearings[entry_intersection.out];
|
||||||
@@ -225,7 +225,8 @@ inline double totalTurnAngle(const RouteStep &entry_step, const RouteStep &exit_
|
|||||||
inline bool bearingsAreReversed(const double bearing_in, const double bearing_out)
|
inline bool bearingsAreReversed(const double bearing_in, const double bearing_out)
|
||||||
{
|
{
|
||||||
// Nearly perfectly reversed angles have a difference close to 180 degrees (straight)
|
// Nearly perfectly reversed angles have a difference close to 180 degrees (straight)
|
||||||
const double left_turn_angle = [&]() {
|
const double left_turn_angle = [&]()
|
||||||
|
{
|
||||||
if (0 <= bearing_out && bearing_out <= bearing_in)
|
if (0 <= bearing_out && bearing_out <= bearing_in)
|
||||||
return bearing_in - bearing_out;
|
return bearing_in - bearing_out;
|
||||||
return bearing_in + 360 - bearing_out;
|
return bearing_in + 360 - bearing_out;
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
#ifndef OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
|
#ifndef OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
|
||||||
#define OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
|
#define OSRM_ENGINE_GUIDANCE_LANE_PROCESSING_HPP_
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "engine/guidance/route_step.hpp"
|
#include "engine/guidance/route_step.hpp"
|
||||||
#include "util/attributes.hpp"
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace osrm::engine::guidance
|
namespace osrm::engine::guidance
|
||||||
{
|
{
|
||||||
@@ -14,9 +13,9 @@ namespace osrm::engine::guidance
|
|||||||
// we anticipate lane changes emitting only matching lanes early on.
|
// we anticipate lane changes emitting only matching lanes early on.
|
||||||
// the second parameter describes the duration that we feel two segments need to be apart to count
|
// the second parameter describes the duration that we feel two segments need to be apart to count
|
||||||
// as separate maneuvers.
|
// as separate maneuvers.
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] std::vector<RouteStep>
|
||||||
std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
|
anticipateLaneChange(std::vector<RouteStep> steps,
|
||||||
const double min_distance_needed_for_lane_change = 200);
|
const double min_distance_needed_for_lane_change = 200);
|
||||||
|
|
||||||
} // namespace osrm::engine::guidance
|
} // namespace osrm::engine::guidance
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include "engine/guidance/leg_geometry.hpp"
|
#include "engine/guidance/leg_geometry.hpp"
|
||||||
#include "engine/guidance/route_step.hpp"
|
#include "engine/guidance/route_step.hpp"
|
||||||
#include "engine/phantom_node.hpp"
|
#include "engine/phantom_node.hpp"
|
||||||
#include "util/attributes.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -13,8 +12,7 @@ namespace osrm::engine::guidance
|
|||||||
{
|
{
|
||||||
|
|
||||||
// passed as none-reference to modify in-place and move out again
|
// passed as none-reference to modify in-place and move out again
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] std::vector<RouteStep> handleRoundabouts(std::vector<RouteStep> steps);
|
||||||
std::vector<RouteStep> handleRoundabouts(std::vector<RouteStep> steps);
|
|
||||||
|
|
||||||
// trim initial/final segment of very short length.
|
// trim initial/final segment of very short length.
|
||||||
// This function uses in/out parameter passing to modify both steps and geometry in place.
|
// This function uses in/out parameter passing to modify both steps and geometry in place.
|
||||||
@@ -24,23 +22,21 @@ std::vector<RouteStep> handleRoundabouts(std::vector<RouteStep> steps);
|
|||||||
void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry);
|
void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry);
|
||||||
|
|
||||||
// assign relative locations to depart/arrive instructions
|
// assign relative locations to depart/arrive instructions
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps,
|
||||||
std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps,
|
const LegGeometry &geometry,
|
||||||
const LegGeometry &geometry,
|
const PhantomNode &source_node,
|
||||||
const PhantomNode &source_node,
|
const PhantomNode &target_node);
|
||||||
const PhantomNode &target_node);
|
|
||||||
|
|
||||||
// collapse suppressed instructions remaining into intersections array
|
// collapse suppressed instructions remaining into intersections array
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps);
|
||||||
std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps);
|
|
||||||
|
|
||||||
// postProcess will break the connection between the leg geometry
|
// postProcess will break the connection between the leg geometry
|
||||||
// for which a segment is supposed to represent exactly the coordinates
|
// for which a segment is supposed to represent exactly the coordinates
|
||||||
// between routing maneuvers and the route steps itself.
|
// between routing maneuvers and the route steps itself.
|
||||||
// If required, we can get both in sync again using this function.
|
// If required, we can get both in sync again using this function.
|
||||||
// Move in LegGeometry for modification in place.
|
// Move in LegGeometry for modification in place.
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] LegGeometry resyncGeometry(LegGeometry leg_geometry,
|
||||||
LegGeometry resyncGeometry(LegGeometry leg_geometry, const std::vector<RouteStep> &steps);
|
const std::vector<RouteStep> &steps);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply maneuver override relations to the selected route.
|
* Apply maneuver override relations to the selected route.
|
||||||
|
|||||||
@@ -20,14 +20,16 @@ template <typename Iter, typename Fn> inline Fn forEachRoundabout(Iter first, It
|
|||||||
{
|
{
|
||||||
while (first != last)
|
while (first != last)
|
||||||
{
|
{
|
||||||
const auto enter = std::find_if(first, last, [](const RouteStep &step) {
|
const auto enter = std::find_if(first,
|
||||||
return entersRoundabout(step.maneuver.instruction);
|
last,
|
||||||
});
|
[](const RouteStep &step)
|
||||||
|
{ return entersRoundabout(step.maneuver.instruction); });
|
||||||
|
|
||||||
// enter has to come before leave, otherwise: faulty data / partial roundabout, skip those
|
// enter has to come before leave, otherwise: faulty data / partial roundabout, skip those
|
||||||
const auto leave = std::find_if(enter, last, [](const RouteStep &step) {
|
const auto leave = std::find_if(enter,
|
||||||
return leavesRoundabout(step.maneuver.instruction);
|
last,
|
||||||
});
|
[](const RouteStep &step)
|
||||||
|
{ return leavesRoundabout(step.maneuver.instruction); });
|
||||||
|
|
||||||
// No roundabouts, or partial one (like start / end inside a roundabout)
|
// No roundabouts, or partial one (like start / end inside a roundabout)
|
||||||
if (enter == last || leave == last)
|
if (enter == last || leave == last)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#define OSRM_ENGINE_GUIDANCE_VERBOSITY_REDUCTION_HPP_
|
#define OSRM_ENGINE_GUIDANCE_VERBOSITY_REDUCTION_HPP_
|
||||||
|
|
||||||
#include "engine/guidance/route_step.hpp"
|
#include "engine/guidance/route_step.hpp"
|
||||||
#include "util/attributes.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -13,8 +12,7 @@ namespace osrm::engine::guidance
|
|||||||
// to announce them. All these that are not collapsed into a single turn (think segregated
|
// to announce them. All these that are not collapsed into a single turn (think segregated
|
||||||
// intersection) have to be checked for the length they are active in. If they are active for a
|
// intersection) have to be checked for the length they are active in. If they are active for a
|
||||||
// short distance only, we don't announce them
|
// short distance only, we don't announce them
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] std::vector<RouteStep> suppressShortNameSegments(std::vector<RouteStep> steps);
|
||||||
std::vector<RouteStep> suppressShortNameSegments(std::vector<RouteStep> steps);
|
|
||||||
|
|
||||||
} // namespace osrm::engine::guidance
|
} // namespace osrm::engine::guidance
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <boost/math/constants/constants.hpp>
|
#include <numbers>
|
||||||
|
|
||||||
namespace osrm::engine::map_matching
|
namespace osrm::engine::map_matching
|
||||||
{
|
{
|
||||||
@@ -21,10 +21,8 @@ struct NormalDistribution
|
|||||||
// FIXME implement log-probability version since it's faster
|
// FIXME implement log-probability version since it's faster
|
||||||
double Density(const double val) const
|
double Density(const double val) const
|
||||||
{
|
{
|
||||||
using namespace boost::math::constants;
|
|
||||||
|
|
||||||
const double x = val - mean;
|
const double x = val - mean;
|
||||||
return 1.0 / (std::sqrt(two_pi<double>()) * standard_deviation) *
|
return 1.0 / (std::sqrt(2 * std::numbers::pi) * standard_deviation) *
|
||||||
std::exp(-x * x / (standard_deviation * standard_deviation));
|
std::exp(-x * x / (standard_deviation * standard_deviation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include "util/integer_range.hpp"
|
#include "util/integer_range.hpp"
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/math/constants/constants.hpp>
|
#include <numbers>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
namespace osrm::engine::map_matching
|
namespace osrm::engine::map_matching
|
||||||
{
|
{
|
||||||
|
|
||||||
static const double log_2_pi = std::log(2. * boost::math::constants::pi<double>());
|
static const double log_2_pi = std::log(2. * std::numbers::pi);
|
||||||
static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits<double>::infinity();
|
static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits<double>::infinity();
|
||||||
static const double MINIMAL_LOG_PROB = std::numeric_limits<double>::lowest();
|
static const double MINIMAL_LOG_PROB = std::numeric_limits<double>::lowest();
|
||||||
static const std::size_t INVALID_STATE = std::numeric_limits<std::size_t>::max();
|
static const std::size_t INVALID_STATE = std::numeric_limits<std::size_t>::max();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#define ENGINE_MAP_MATCHING_CONFIDENCE_HPP
|
#define ENGINE_MAP_MATCHING_CONFIDENCE_HPP
|
||||||
|
|
||||||
#include "engine/map_matching/bayes_classifier.hpp"
|
#include "engine/map_matching/bayes_classifier.hpp"
|
||||||
|
#include <boost/assert.hpp>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace osrm::engine::map_matching
|
namespace osrm::engine::map_matching
|
||||||
|
|||||||
@@ -259,10 +259,10 @@ inline util::Coordinate candidatesInputLocation(const PhantomNodeCandidates &can
|
|||||||
|
|
||||||
inline bool candidatesHaveComponent(const PhantomNodeCandidates &candidates, uint32_t component_id)
|
inline bool candidatesHaveComponent(const PhantomNodeCandidates &candidates, uint32_t component_id)
|
||||||
{
|
{
|
||||||
return std::any_of(
|
return std::any_of(candidates.begin(),
|
||||||
candidates.begin(), candidates.end(), [component_id](const PhantomNode &node) {
|
candidates.end(),
|
||||||
return node.component.id == component_id;
|
[component_id](const PhantomNode &node)
|
||||||
});
|
{ return node.component.id == component_id; });
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PhantomEndpoints
|
struct PhantomEndpoints
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ class BasePlugin
|
|||||||
|
|
||||||
bool CheckAllCoordinates(const std::vector<util::Coordinate> &coordinates) const
|
bool CheckAllCoordinates(const std::vector<util::Coordinate> &coordinates) const
|
||||||
{
|
{
|
||||||
return !std::any_of(
|
return !std::any_of(std::begin(coordinates),
|
||||||
std::begin(coordinates), std::end(coordinates), [](const util::Coordinate coordinate) {
|
std::end(coordinates),
|
||||||
return !coordinate.IsValid();
|
[](const util::Coordinate coordinate)
|
||||||
});
|
{ return !coordinate.IsValid(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckAlgorithms(const api::BaseParameters ¶ms,
|
bool CheckAlgorithms(const api::BaseParameters ¶ms,
|
||||||
@@ -95,7 +95,7 @@ class BasePlugin
|
|||||||
const std::string &message,
|
const std::string &message,
|
||||||
osrm::engine::api::ResultT &result) const
|
osrm::engine::api::ResultT &result) const
|
||||||
{
|
{
|
||||||
mapbox::util::apply_visitor(ErrorRenderer(code, message), result);
|
std::visit(ErrorRenderer(code, message), result);
|
||||||
return Status::Error;
|
return Status::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,45 +105,45 @@ class BasePlugin
|
|||||||
{
|
{
|
||||||
// are all phantoms from a tiny cc?
|
// are all phantoms from a tiny cc?
|
||||||
const auto all_in_same_tiny_component =
|
const auto all_in_same_tiny_component =
|
||||||
[](const std::vector<PhantomCandidateAlternatives> &alts_list) {
|
[](const std::vector<PhantomCandidateAlternatives> &alts_list)
|
||||||
return std::any_of(
|
{
|
||||||
alts_list.front().first.begin(),
|
return std::any_of(
|
||||||
alts_list.front().first.end(),
|
alts_list.front().first.begin(),
|
||||||
// For each of the first possible phantoms, check if all other
|
alts_list.front().first.end(),
|
||||||
// positions in the list have a phantom from the same small component.
|
// For each of the first possible phantoms, check if all other
|
||||||
[&](const PhantomNode &phantom) {
|
// positions in the list have a phantom from the same small component.
|
||||||
if (!phantom.component.is_tiny)
|
[&](const PhantomNode &phantom)
|
||||||
{
|
{
|
||||||
return false;
|
if (!phantom.component.is_tiny)
|
||||||
}
|
{
|
||||||
const auto component_id = phantom.component.id;
|
return false;
|
||||||
return std::all_of(
|
}
|
||||||
std::next(alts_list.begin()),
|
const auto component_id = phantom.component.id;
|
||||||
std::end(alts_list),
|
return std::all_of(
|
||||||
[component_id](const PhantomCandidateAlternatives &alternatives) {
|
std::next(alts_list.begin()),
|
||||||
return candidatesHaveComponent(alternatives.first, component_id);
|
std::end(alts_list),
|
||||||
});
|
[component_id](const PhantomCandidateAlternatives &alternatives)
|
||||||
});
|
{ return candidatesHaveComponent(alternatives.first, component_id); });
|
||||||
};
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Move the alternative into the final list
|
// Move the alternative into the final list
|
||||||
const auto fallback_to_big_component = [](PhantomCandidateAlternatives &alternatives) {
|
const auto fallback_to_big_component = [](PhantomCandidateAlternatives &alternatives)
|
||||||
|
{
|
||||||
auto no_big_alternative = alternatives.second.empty();
|
auto no_big_alternative = alternatives.second.empty();
|
||||||
return no_big_alternative ? std::move(alternatives.first)
|
return no_big_alternative ? std::move(alternatives.first)
|
||||||
: std::move(alternatives.second);
|
: std::move(alternatives.second);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Move the alternative into the final list
|
// Move the alternative into the final list
|
||||||
const auto use_closed_phantom = [](PhantomCandidateAlternatives &alternatives) {
|
const auto use_closed_phantom = [](PhantomCandidateAlternatives &alternatives)
|
||||||
return std::move(alternatives.first);
|
{ return std::move(alternatives.first); };
|
||||||
};
|
|
||||||
|
|
||||||
const auto no_alternatives =
|
const auto no_alternatives =
|
||||||
std::all_of(alternatives_list.begin(),
|
std::all_of(alternatives_list.begin(),
|
||||||
alternatives_list.end(),
|
alternatives_list.end(),
|
||||||
[](const PhantomCandidateAlternatives &alternatives) {
|
[](const PhantomCandidateAlternatives &alternatives)
|
||||||
return alternatives.second.empty();
|
{ return alternatives.second.empty(); });
|
||||||
});
|
|
||||||
|
|
||||||
std::vector<PhantomNodeCandidates> snapped_phantoms;
|
std::vector<PhantomNodeCandidates> snapped_phantoms;
|
||||||
snapped_phantoms.reserve(alternatives_list.size());
|
snapped_phantoms.reserve(alternatives_list.size());
|
||||||
@@ -313,12 +313,12 @@ class BasePlugin
|
|||||||
alternatives.end(),
|
alternatives.end(),
|
||||||
coordinates.begin(),
|
coordinates.begin(),
|
||||||
coordinates.end(),
|
coordinates.end(),
|
||||||
[](const auto &candidates_pair, const auto &coordinate) {
|
[](const auto &candidates_pair, const auto &coordinate)
|
||||||
|
{
|
||||||
return std::any_of(candidates_pair.first.begin(),
|
return std::any_of(candidates_pair.first.begin(),
|
||||||
candidates_pair.first.end(),
|
candidates_pair.first.end(),
|
||||||
[&](const auto &phantom) {
|
[&](const auto &phantom)
|
||||||
return phantom.input_location == coordinate;
|
{ return phantom.input_location == coordinate; });
|
||||||
});
|
|
||||||
});
|
});
|
||||||
std::size_t missing_index = std::distance(alternatives.begin(), mismatch.first);
|
std::size_t missing_index = std::distance(alternatives.begin(), mismatch.first);
|
||||||
return std::string("Could not find a matching segment for coordinate ") +
|
return std::string("Could not find a matching segment for coordinate ") +
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace osrm::engine
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
std::string encode(std::vector<int> &numbers);
|
void encode(int number_to_encode, std::string &output);
|
||||||
std::int32_t decode_polyline_integer(std::string::const_iterator &first,
|
std::int32_t decode_polyline_integer(std::string::const_iterator &first,
|
||||||
std::string::const_iterator last);
|
std::string::const_iterator last);
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@@ -30,26 +30,24 @@ std::string encodePolyline(CoordVectorForwardIter begin, CoordVectorForwardIter
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> delta_numbers;
|
std::string output;
|
||||||
BOOST_ASSERT(size > 0);
|
// just a guess that we will need ~4 bytes per coordinate to avoid reallocations
|
||||||
delta_numbers.reserve((size - 1) * 2);
|
output.reserve(size * 4);
|
||||||
|
|
||||||
int current_lat = 0;
|
int current_lat = 0;
|
||||||
int current_lon = 0;
|
int current_lon = 0;
|
||||||
std::for_each(
|
for (auto it = begin; it != end; ++it)
|
||||||
begin,
|
{
|
||||||
end,
|
const int lat_diff =
|
||||||
[&delta_numbers, ¤t_lat, ¤t_lon, coordinate_to_polyline](
|
std::round(static_cast<int>(it->lat) * coordinate_to_polyline) - current_lat;
|
||||||
const util::Coordinate loc) {
|
const int lon_diff =
|
||||||
const int lat_diff =
|
std::round(static_cast<int>(it->lon) * coordinate_to_polyline) - current_lon;
|
||||||
std::round(static_cast<int>(loc.lat) * coordinate_to_polyline) - current_lat;
|
detail::encode(lat_diff, output);
|
||||||
const int lon_diff =
|
detail::encode(lon_diff, output);
|
||||||
std::round(static_cast<int>(loc.lon) * coordinate_to_polyline) - current_lon;
|
current_lat += lat_diff;
|
||||||
delta_numbers.emplace_back(lat_diff);
|
current_lon += lon_diff;
|
||||||
delta_numbers.emplace_back(lon_diff);
|
}
|
||||||
current_lat += lat_diff;
|
return output;
|
||||||
current_lon += lon_diff;
|
|
||||||
});
|
|
||||||
return detail::encode(delta_numbers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decodes geometry from polyline format
|
// Decodes geometry from polyline format
|
||||||
|
|||||||
@@ -71,24 +71,27 @@ void insertTargetInReverseHeap(Heap &reverse_heap, const PhantomNode &target)
|
|||||||
static constexpr bool FORWARD_DIRECTION = true;
|
static constexpr bool FORWARD_DIRECTION = true;
|
||||||
static constexpr bool REVERSE_DIRECTION = false;
|
static constexpr bool REVERSE_DIRECTION = false;
|
||||||
|
|
||||||
// Identify nodes in the forward(reverse) search direction that will require loop forcing
|
// Identify nodes in the forward(reverse) search direction that will require step forcing
|
||||||
// e.g. if source and destination nodes are on the same segment.
|
// e.g. if source and destination nodes are on the same segment.
|
||||||
std::vector<NodeID> getForwardLoopNodes(const PhantomEndpointCandidates &candidates);
|
std::vector<NodeID> getForwardForceNodes(const PhantomEndpointCandidates &candidates);
|
||||||
std::vector<NodeID> getForwardLoopNodes(const PhantomCandidatesToTarget &candidates);
|
std::vector<NodeID> getForwardForceNodes(const PhantomCandidatesToTarget &candidates);
|
||||||
std::vector<NodeID> getBackwardLoopNodes(const PhantomEndpointCandidates &candidates);
|
std::vector<NodeID> getBackwardForceNodes(const PhantomEndpointCandidates &candidates);
|
||||||
std::vector<NodeID> getBackwardLoopNodes(const PhantomCandidatesToTarget &candidates);
|
std::vector<NodeID> getBackwardForceNodes(const PhantomCandidatesToTarget &candidates);
|
||||||
|
|
||||||
// Find the specific phantom node endpoints for a given path from a list of candidates.
|
// Find the specific phantom node endpoints for a given path from a list of candidates.
|
||||||
PhantomEndpoints endpointsFromCandidates(const PhantomEndpointCandidates &candidates,
|
PhantomEndpoints endpointsFromCandidates(const PhantomEndpointCandidates &candidates,
|
||||||
const std::vector<NodeID> &path);
|
const std::vector<NodeID> &path);
|
||||||
|
|
||||||
template <typename HeapNodeT>
|
template <typename HeapNodeT>
|
||||||
inline bool force_loop(const std::vector<NodeID> &force_nodes, const HeapNodeT &heap_node)
|
inline bool shouldForceStep(const std::vector<NodeID> &force_nodes,
|
||||||
|
const HeapNodeT &forward_heap_node,
|
||||||
|
const HeapNodeT &reverse_heap_node)
|
||||||
{
|
{
|
||||||
// if loops are forced, they are so at the source
|
// routing steps are forced when the node is a source of both forward and reverse search heaps.
|
||||||
return !force_nodes.empty() &&
|
return forward_heap_node.data.parent == forward_heap_node.node &&
|
||||||
std::find(force_nodes.begin(), force_nodes.end(), heap_node.node) != force_nodes.end() &&
|
reverse_heap_node.data.parent == reverse_heap_node.node &&
|
||||||
heap_node.data.parent == heap_node.node;
|
std::find(force_nodes.begin(), force_nodes.end(), forward_heap_node.node) !=
|
||||||
|
force_nodes.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Heap>
|
template <typename Heap>
|
||||||
@@ -190,8 +193,10 @@ void annotatePath(const FacadeT &facade,
|
|||||||
std::vector<SegmentDuration> duration_vector;
|
std::vector<SegmentDuration> duration_vector;
|
||||||
std::vector<DatasourceID> datasource_vector;
|
std::vector<DatasourceID> datasource_vector;
|
||||||
|
|
||||||
const auto get_segment_geometry = [&](const auto geometry_index) {
|
const auto get_segment_geometry = [&](const auto geometry_index)
|
||||||
const auto copy = [](auto &vector, const auto range) {
|
{
|
||||||
|
const auto copy = [](auto &vector, const auto range)
|
||||||
|
{
|
||||||
vector.resize(range.size());
|
vector.resize(range.size());
|
||||||
std::copy(range.begin(), range.end(), vector.begin());
|
std::copy(range.begin(), range.end(), vector.begin());
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -112,8 +112,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
|||||||
NodeID &middle_node_id,
|
NodeID &middle_node_id,
|
||||||
EdgeWeight &upper_bound,
|
EdgeWeight &upper_bound,
|
||||||
EdgeWeight min_edge_offset,
|
EdgeWeight min_edge_offset,
|
||||||
const std::vector<NodeID> &force_loop_forward_nodes,
|
const std::vector<NodeID> &force_step_nodes)
|
||||||
const std::vector<NodeID> &force_loop_reverse_nodes)
|
|
||||||
{
|
{
|
||||||
auto heapNode = forward_heap.DeleteMinGetHeapNode();
|
auto heapNode = forward_heap.DeleteMinGetHeapNode();
|
||||||
const auto reverseHeapNode = reverse_heap.GetHeapNodeIfWasInserted(heapNode.node);
|
const auto reverseHeapNode = reverse_heap.GetHeapNodeIfWasInserted(heapNode.node);
|
||||||
@@ -123,13 +122,13 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
|||||||
const EdgeWeight new_weight = reverseHeapNode->weight + heapNode.weight;
|
const EdgeWeight new_weight = reverseHeapNode->weight + heapNode.weight;
|
||||||
if (new_weight < upper_bound)
|
if (new_weight < upper_bound)
|
||||||
{
|
{
|
||||||
if (force_loop(force_loop_forward_nodes, heapNode) ||
|
if (shouldForceStep(force_step_nodes, heapNode, *reverseHeapNode) ||
|
||||||
force_loop(force_loop_reverse_nodes, heapNode) ||
|
|
||||||
// in this case we are looking at a bi-directional way where the source
|
// in this case we are looking at a bi-directional way where the source
|
||||||
// and target phantom are on the same edge based node
|
// and target phantom are on the same edge based node
|
||||||
new_weight < EdgeWeight{0})
|
new_weight < EdgeWeight{0})
|
||||||
{
|
{
|
||||||
// check whether there is a loop present at the node
|
// Before forcing step, check whether there is a loop present at the node.
|
||||||
|
// We may find a valid weight path by following the loop.
|
||||||
for (const auto edge : facade.GetAdjacentEdgeRange(heapNode.node))
|
for (const auto edge : facade.GetAdjacentEdgeRange(heapNode.node))
|
||||||
{
|
{
|
||||||
const auto &data = facade.GetEdgeData(edge);
|
const auto &data = facade.GetEdgeData(edge);
|
||||||
@@ -294,9 +293,9 @@ EdgeDistance calculateEBGNodeAnnotations(const DataFacade<Algorithm> &facade,
|
|||||||
|
|
||||||
// Look for an edge on the forward CH graph (.forward)
|
// Look for an edge on the forward CH graph (.forward)
|
||||||
EdgeID smaller_edge_id =
|
EdgeID smaller_edge_id =
|
||||||
facade.FindSmallestEdge(std::get<0>(edge), std::get<1>(edge), [](const auto &data) {
|
facade.FindSmallestEdge(std::get<0>(edge),
|
||||||
return data.forward;
|
std::get<1>(edge),
|
||||||
});
|
[](const auto &data) { return data.forward; });
|
||||||
|
|
||||||
// If we didn't find one there, the we might be looking at a part of the path that
|
// If we didn't find one there, the we might be looking at a part of the path that
|
||||||
// was found using the backward search. Here, we flip the node order (.second,
|
// was found using the backward search. Here, we flip the node order (.second,
|
||||||
@@ -381,7 +380,8 @@ void unpackPath(const FacadeT &facade,
|
|||||||
unpackPath(facade,
|
unpackPath(facade,
|
||||||
packed_path_begin,
|
packed_path_begin,
|
||||||
packed_path_end,
|
packed_path_end,
|
||||||
[&](std::pair<NodeID, NodeID> &edge, const auto &edge_id) {
|
[&](std::pair<NodeID, NodeID> &edge, const auto &edge_id)
|
||||||
|
{
|
||||||
BOOST_ASSERT(edge.first == unpacked_nodes.back());
|
BOOST_ASSERT(edge.first == unpacked_nodes.back());
|
||||||
unpacked_nodes.push_back(edge.second);
|
unpacked_nodes.push_back(edge.second);
|
||||||
unpacked_edges.push_back(edge_id);
|
unpacked_edges.push_back(edge_id);
|
||||||
@@ -420,23 +420,22 @@ void retrievePackedPathFromSingleManyToManyHeap(
|
|||||||
// assumes that heaps are already setup correctly.
|
// assumes that heaps are already setup correctly.
|
||||||
// ATTENTION: This only works if no additional offset is supplied next to the Phantom Node
|
// ATTENTION: This only works if no additional offset is supplied next to the Phantom Node
|
||||||
// Offsets.
|
// Offsets.
|
||||||
// In case additional offsets are supplied, you might have to force a loop first.
|
// In case additional offsets are supplied, you might have to force a routing step first.
|
||||||
// A forced loop might be necessary, if source and target are on the same segment.
|
// A forced step might be necessary, if source and target are on the same segment.
|
||||||
// If this is the case and the offsets of the respective direction are larger for the source
|
// If this is the case and the offsets of the respective direction are larger for the source
|
||||||
// than the target
|
// than the target
|
||||||
// then a force loop is required (e.g. source_phantom.forward_segment_id ==
|
// then a force step is required (e.g. source_phantom.forward_segment_id ==
|
||||||
// target_phantom.forward_segment_id
|
// target_phantom.forward_segment_id
|
||||||
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
||||||
// requires
|
// requires
|
||||||
// a force loop, if the heaps have been initialized with positive offsets.
|
// a force step, if the heaps have been initialized with positive offsets.
|
||||||
void search(SearchEngineData<Algorithm> &engine_working_data,
|
void search(SearchEngineData<Algorithm> &engine_working_data,
|
||||||
const DataFacade<Algorithm> &facade,
|
const DataFacade<Algorithm> &facade,
|
||||||
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
||||||
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
||||||
EdgeWeight &weight,
|
EdgeWeight &weight,
|
||||||
std::vector<NodeID> &packed_leg,
|
std::vector<NodeID> &packed_leg,
|
||||||
const std::vector<NodeID> &force_loop_forward_node,
|
const std::vector<NodeID> &force_step_nodes,
|
||||||
const std::vector<NodeID> &force_loop_reverse_node,
|
|
||||||
const EdgeWeight duration_upper_bound = INVALID_EDGE_WEIGHT);
|
const EdgeWeight duration_upper_bound = INVALID_EDGE_WEIGHT);
|
||||||
|
|
||||||
template <typename PhantomEndpointT>
|
template <typename PhantomEndpointT>
|
||||||
@@ -446,8 +445,7 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
||||||
EdgeWeight &weight,
|
EdgeWeight &weight,
|
||||||
std::vector<NodeID> &packed_leg,
|
std::vector<NodeID> &packed_leg,
|
||||||
const std::vector<NodeID> &force_loop_forward_node,
|
const std::vector<NodeID> &force_step_nodes,
|
||||||
const std::vector<NodeID> &force_loop_reverse_node,
|
|
||||||
const PhantomEndpointT & /*endpoints*/,
|
const PhantomEndpointT & /*endpoints*/,
|
||||||
const EdgeWeight duration_upper_bound = INVALID_EDGE_WEIGHT)
|
const EdgeWeight duration_upper_bound = INVALID_EDGE_WEIGHT)
|
||||||
{
|
{
|
||||||
@@ -458,14 +456,13 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
reverse_heap,
|
reverse_heap,
|
||||||
weight,
|
weight,
|
||||||
packed_leg,
|
packed_leg,
|
||||||
force_loop_forward_node,
|
force_step_nodes,
|
||||||
force_loop_reverse_node,
|
|
||||||
duration_upper_bound);
|
duration_upper_bound);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Requires the heaps for be empty
|
// Requires the heaps for be empty
|
||||||
// If heaps should be adjusted to be initialized outside of this function,
|
// If heaps should be adjusted to be initialized outside of this function,
|
||||||
// the addition of force_loop parameters might be required
|
// the addition of force_step parameters might be required
|
||||||
double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
||||||
const DataFacade<ch::Algorithm> &facade,
|
const DataFacade<ch::Algorithm> &facade,
|
||||||
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <boost/core/ignore_unused.hpp>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
@@ -30,7 +31,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
|||||||
const PhantomNode &source,
|
const PhantomNode &source,
|
||||||
const PhantomNode &target)
|
const PhantomNode &target)
|
||||||
{
|
{
|
||||||
auto level = [&partition, node](const SegmentID &source, const SegmentID &target) {
|
auto level = [&partition, node](const SegmentID &source, const SegmentID &target)
|
||||||
|
{
|
||||||
if (source.enabled && target.enabled)
|
if (source.enabled && target.enabled)
|
||||||
return partition.GetQueryLevel(source.id, target.id, node);
|
return partition.GetQueryLevel(source.id, target.id, node);
|
||||||
return INVALID_LEVEL_ID;
|
return INVALID_LEVEL_ID;
|
||||||
@@ -59,7 +61,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
|||||||
endpoint_candidates.source_phantoms.begin(),
|
endpoint_candidates.source_phantoms.begin(),
|
||||||
endpoint_candidates.source_phantoms.end(),
|
endpoint_candidates.source_phantoms.end(),
|
||||||
INVALID_LEVEL_ID,
|
INVALID_LEVEL_ID,
|
||||||
[&](LevelID current_level, const PhantomNode &source) {
|
[&](LevelID current_level, const PhantomNode &source)
|
||||||
|
{
|
||||||
return std::min(
|
return std::min(
|
||||||
current_level,
|
current_level,
|
||||||
getNodeQueryLevel(partition, node, source, endpoint_candidates.target_phantom));
|
getNodeQueryLevel(partition, node, source, endpoint_candidates.target_phantom));
|
||||||
@@ -76,7 +79,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
|||||||
endpoint_candidates.source_phantoms.begin(),
|
endpoint_candidates.source_phantoms.begin(),
|
||||||
endpoint_candidates.source_phantoms.end(),
|
endpoint_candidates.source_phantoms.end(),
|
||||||
INVALID_LEVEL_ID,
|
INVALID_LEVEL_ID,
|
||||||
[&](LevelID level_1, const PhantomNode &source) {
|
[&](LevelID level_1, const PhantomNode &source)
|
||||||
|
{
|
||||||
return std::min(
|
return std::min(
|
||||||
level_1,
|
level_1,
|
||||||
std::accumulate(endpoint_candidates.target_phantoms.begin(),
|
std::accumulate(endpoint_candidates.target_phantoms.begin(),
|
||||||
@@ -119,7 +123,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
|||||||
const NodeID node,
|
const NodeID node,
|
||||||
const PhantomNodeCandidates &candidates)
|
const PhantomNodeCandidates &candidates)
|
||||||
{
|
{
|
||||||
auto highest_different_level = [&partition, node](const SegmentID &segment) {
|
auto highest_different_level = [&partition, node](const SegmentID &segment)
|
||||||
|
{
|
||||||
return segment.enabled ? partition.GetHighestDifferentLevel(segment.id, node)
|
return segment.enabled ? partition.GetHighestDifferentLevel(segment.id, node)
|
||||||
: INVALID_LEVEL_ID;
|
: INVALID_LEVEL_ID;
|
||||||
};
|
};
|
||||||
@@ -128,7 +133,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
|||||||
std::accumulate(candidates.begin(),
|
std::accumulate(candidates.begin(),
|
||||||
candidates.end(),
|
candidates.end(),
|
||||||
INVALID_LEVEL_ID,
|
INVALID_LEVEL_ID,
|
||||||
[&](LevelID current_level, const PhantomNode &phantom_node) {
|
[&](LevelID current_level, const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
auto highest_level =
|
auto highest_level =
|
||||||
std::min(highest_different_level(phantom_node.forward_segment_id),
|
std::min(highest_different_level(phantom_node.forward_segment_id),
|
||||||
highest_different_level(phantom_node.reverse_segment_id));
|
highest_different_level(phantom_node.reverse_segment_id));
|
||||||
@@ -151,9 +157,11 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
|||||||
// This is equivalent to min_{∀ source, target} partition.GetQueryLevel(source, node, target)
|
// This is equivalent to min_{∀ source, target} partition.GetQueryLevel(source, node, target)
|
||||||
auto init = getNodeQueryLevel(partition, node, candidates_list[phantom_index]);
|
auto init = getNodeQueryLevel(partition, node, candidates_list[phantom_index]);
|
||||||
auto result = std::accumulate(
|
auto result = std::accumulate(
|
||||||
phantom_indices.begin(), phantom_indices.end(), init, [&](LevelID level, size_t index) {
|
phantom_indices.begin(),
|
||||||
return std::min(level, getNodeQueryLevel(partition, node, candidates_list[index]));
|
phantom_indices.end(),
|
||||||
});
|
init,
|
||||||
|
[&](LevelID level, size_t index)
|
||||||
|
{ return std::min(level, getNodeQueryLevel(partition, node, candidates_list[index])); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -262,11 +270,30 @@ retrievePackedPathFromHeap(const SearchEngineData<Algorithm>::QueryHeap &forward
|
|||||||
return packed_path;
|
return packed_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool DIRECTION, typename Algorithm, typename... Args>
|
template <typename Heap>
|
||||||
|
void insertOrUpdate(Heap &heap,
|
||||||
|
const NodeID node,
|
||||||
|
const EdgeWeight weight,
|
||||||
|
const typename Heap::DataType &data)
|
||||||
|
{
|
||||||
|
const auto heapNode = heap.GetHeapNodeIfWasInserted(node);
|
||||||
|
if (!heapNode)
|
||||||
|
{
|
||||||
|
heap.Insert(node, weight, data);
|
||||||
|
}
|
||||||
|
else if (weight < heapNode->weight)
|
||||||
|
{
|
||||||
|
heapNode->data = data;
|
||||||
|
heapNode->weight = weight;
|
||||||
|
heap.DecreaseKey(*heapNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool DIRECTION, typename Algorithm, typename Heap, typename... Args>
|
||||||
void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
|
void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
|
||||||
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
Heap &forward_heap,
|
||||||
const typename SearchEngineData<Algorithm>::QueryHeap::HeapNode &heapNode,
|
const typename Heap::HeapNode &heapNode,
|
||||||
const Args &... args)
|
const Args &...args)
|
||||||
{
|
{
|
||||||
const auto &partition = facade.GetMultiLevelPartition();
|
const auto &partition = facade.GetMultiLevelPartition();
|
||||||
const auto &cells = facade.GetCellStorage();
|
const auto &cells = facade.GetCellStorage();
|
||||||
@@ -274,14 +301,31 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
|
|||||||
|
|
||||||
const auto level = getNodeQueryLevel(partition, heapNode.node, args...);
|
const auto level = getNodeQueryLevel(partition, heapNode.node, args...);
|
||||||
|
|
||||||
|
static constexpr auto IS_MAP_MATCHING =
|
||||||
|
std::is_same_v<typename SearchEngineData<mld::Algorithm>::MapMatchingQueryHeap, Heap>;
|
||||||
|
|
||||||
if (level >= 1 && !heapNode.data.from_clique_arc)
|
if (level >= 1 && !heapNode.data.from_clique_arc)
|
||||||
{
|
{
|
||||||
if (DIRECTION == FORWARD_DIRECTION)
|
if constexpr (DIRECTION == FORWARD_DIRECTION)
|
||||||
{
|
{
|
||||||
// Shortcuts in forward direction
|
// Shortcuts in forward direction
|
||||||
const auto &cell =
|
const auto &cell =
|
||||||
cells.GetCell(metric, level, partition.GetCell(level, heapNode.node));
|
cells.GetCell(metric, level, partition.GetCell(level, heapNode.node));
|
||||||
auto destination = cell.GetDestinationNodes().begin();
|
auto destination = cell.GetDestinationNodes().begin();
|
||||||
|
auto distance = [&cell, node = heapNode.node ]() -> auto
|
||||||
|
{
|
||||||
|
if constexpr (IS_MAP_MATCHING)
|
||||||
|
{
|
||||||
|
|
||||||
|
return cell.GetOutDistance(node).begin();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boost::ignore_unused(cell, node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
();
|
||||||
for (auto shortcut_weight : cell.GetOutWeight(heapNode.node))
|
for (auto shortcut_weight : cell.GetOutWeight(heapNode.node))
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(destination != cell.GetDestinationNodes().end());
|
BOOST_ASSERT(destination != cell.GetDestinationNodes().end());
|
||||||
@@ -291,19 +335,23 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
|
|||||||
{
|
{
|
||||||
const EdgeWeight to_weight = heapNode.weight + shortcut_weight;
|
const EdgeWeight to_weight = heapNode.weight + shortcut_weight;
|
||||||
BOOST_ASSERT(to_weight >= heapNode.weight);
|
BOOST_ASSERT(to_weight >= heapNode.weight);
|
||||||
const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
|
|
||||||
if (!toHeapNode)
|
if constexpr (IS_MAP_MATCHING)
|
||||||
{
|
{
|
||||||
forward_heap.Insert(to, to_weight, {heapNode.node, true});
|
const EdgeDistance to_distance = heapNode.data.distance + *distance;
|
||||||
|
insertOrUpdate(
|
||||||
|
forward_heap, to, to_weight, {heapNode.node, true, to_distance});
|
||||||
}
|
}
|
||||||
else if (to_weight < toHeapNode->weight)
|
else
|
||||||
{
|
{
|
||||||
toHeapNode->data = {heapNode.node, true};
|
insertOrUpdate(forward_heap, to, to_weight, {heapNode.node, true});
|
||||||
toHeapNode->weight = to_weight;
|
|
||||||
forward_heap.DecreaseKey(*toHeapNode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++destination;
|
++destination;
|
||||||
|
if constexpr (IS_MAP_MATCHING)
|
||||||
|
{
|
||||||
|
++distance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -312,6 +360,20 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
|
|||||||
const auto &cell =
|
const auto &cell =
|
||||||
cells.GetCell(metric, level, partition.GetCell(level, heapNode.node));
|
cells.GetCell(metric, level, partition.GetCell(level, heapNode.node));
|
||||||
auto source = cell.GetSourceNodes().begin();
|
auto source = cell.GetSourceNodes().begin();
|
||||||
|
auto distance = [&cell, node = heapNode.node ]() -> auto
|
||||||
|
{
|
||||||
|
if constexpr (IS_MAP_MATCHING)
|
||||||
|
{
|
||||||
|
|
||||||
|
return cell.GetInDistance(node).begin();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boost::ignore_unused(cell, node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
();
|
||||||
for (auto shortcut_weight : cell.GetInWeight(heapNode.node))
|
for (auto shortcut_weight : cell.GetInWeight(heapNode.node))
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(source != cell.GetSourceNodes().end());
|
BOOST_ASSERT(source != cell.GetSourceNodes().end());
|
||||||
@@ -321,19 +383,22 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
|
|||||||
{
|
{
|
||||||
const EdgeWeight to_weight = heapNode.weight + shortcut_weight;
|
const EdgeWeight to_weight = heapNode.weight + shortcut_weight;
|
||||||
BOOST_ASSERT(to_weight >= heapNode.weight);
|
BOOST_ASSERT(to_weight >= heapNode.weight);
|
||||||
const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
|
if constexpr (IS_MAP_MATCHING)
|
||||||
if (!toHeapNode)
|
|
||||||
{
|
{
|
||||||
forward_heap.Insert(to, to_weight, {heapNode.node, true});
|
const EdgeDistance to_distance = heapNode.data.distance + *distance;
|
||||||
|
insertOrUpdate(
|
||||||
|
forward_heap, to, to_weight, {heapNode.node, true, to_distance});
|
||||||
}
|
}
|
||||||
else if (to_weight < toHeapNode->weight)
|
else
|
||||||
{
|
{
|
||||||
toHeapNode->data = {heapNode.node, true};
|
insertOrUpdate(forward_heap, to, to_weight, {heapNode.node, true});
|
||||||
toHeapNode->weight = to_weight;
|
|
||||||
forward_heap.DecreaseKey(*toHeapNode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++source;
|
++source;
|
||||||
|
if constexpr (IS_MAP_MATCHING)
|
||||||
|
{
|
||||||
|
++distance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -360,31 +425,32 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
|
|||||||
const EdgeWeight to_weight =
|
const EdgeWeight to_weight =
|
||||||
heapNode.weight + node_weight + alias_cast<EdgeWeight>(turn_penalty);
|
heapNode.weight + node_weight + alias_cast<EdgeWeight>(turn_penalty);
|
||||||
|
|
||||||
const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
|
if constexpr (IS_MAP_MATCHING)
|
||||||
if (!toHeapNode)
|
|
||||||
{
|
{
|
||||||
forward_heap.Insert(to, to_weight, {heapNode.node, false});
|
const auto node_distance =
|
||||||
|
facade.GetNodeDistance(DIRECTION == FORWARD_DIRECTION ? heapNode.node : to);
|
||||||
|
|
||||||
|
const EdgeDistance to_distance = heapNode.data.distance + node_distance;
|
||||||
|
insertOrUpdate(
|
||||||
|
forward_heap, to, to_weight, {heapNode.node, false, to_distance});
|
||||||
}
|
}
|
||||||
else if (to_weight < toHeapNode->weight)
|
else
|
||||||
{
|
{
|
||||||
toHeapNode->data = {heapNode.node, false};
|
insertOrUpdate(forward_heap, to, to_weight, {heapNode.node, false});
|
||||||
toHeapNode->weight = to_weight;
|
|
||||||
forward_heap.DecreaseKey(*toHeapNode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool DIRECTION, typename Algorithm, typename... Args>
|
template <bool DIRECTION, typename Algorithm, typename Heap, typename... Args>
|
||||||
void routingStep(const DataFacade<Algorithm> &facade,
|
void routingStep(const DataFacade<Algorithm> &facade,
|
||||||
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
Heap &forward_heap,
|
||||||
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
Heap &reverse_heap,
|
||||||
NodeID &middle_node,
|
NodeID &middle_node,
|
||||||
EdgeWeight &path_upper_bound,
|
EdgeWeight &path_upper_bound,
|
||||||
const std::vector<NodeID> &force_loop_forward_nodes,
|
const std::vector<NodeID> &force_step_nodes,
|
||||||
const std::vector<NodeID> &force_loop_reverse_nodes,
|
const Args &...args)
|
||||||
const Args &... args)
|
|
||||||
{
|
{
|
||||||
const auto heapNode = forward_heap.DeleteMinGetHeapNode();
|
const auto heapNode = forward_heap.DeleteMinGetHeapNode();
|
||||||
const auto weight = heapNode.weight;
|
const auto weight = heapNode.weight;
|
||||||
@@ -402,11 +468,8 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
|||||||
auto reverse_weight = reverseHeapNode->weight;
|
auto reverse_weight = reverseHeapNode->weight;
|
||||||
auto path_weight = weight + reverse_weight;
|
auto path_weight = weight + reverse_weight;
|
||||||
|
|
||||||
// MLD uses loops forcing only to prune single node paths in forward and/or
|
if (!shouldForceStep(force_step_nodes, heapNode, *reverseHeapNode) &&
|
||||||
// backward direction (there is no need to force loops in MLD but in CH)
|
(path_weight >= EdgeWeight{0}) && (path_weight < path_upper_bound))
|
||||||
if (!force_loop(force_loop_forward_nodes, heapNode) &&
|
|
||||||
!force_loop(force_loop_reverse_nodes, heapNode) && (path_weight >= EdgeWeight{0}) &&
|
|
||||||
(path_weight < path_upper_bound))
|
|
||||||
{
|
{
|
||||||
middle_node = heapNode.node;
|
middle_node = heapNode.node;
|
||||||
path_upper_bound = path_weight;
|
path_upper_bound = path_weight;
|
||||||
@@ -426,23 +489,19 @@ using UnpackedNodes = std::vector<NodeID>;
|
|||||||
using UnpackedEdges = std::vector<EdgeID>;
|
using UnpackedEdges = std::vector<EdgeID>;
|
||||||
using UnpackedPath = std::tuple<EdgeWeight, UnpackedNodes, UnpackedEdges>;
|
using UnpackedPath = std::tuple<EdgeWeight, UnpackedNodes, UnpackedEdges>;
|
||||||
|
|
||||||
template <typename Algorithm, typename... Args>
|
template <typename Algorithm, typename Heap, typename... Args>
|
||||||
UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
std::optional<std::pair<NodeID, EdgeWeight>> runSearch(const DataFacade<Algorithm> &facade,
|
||||||
const DataFacade<Algorithm> &facade,
|
Heap &forward_heap,
|
||||||
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
Heap &reverse_heap,
|
||||||
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
const std::vector<NodeID> &force_step_nodes,
|
||||||
const std::vector<NodeID> &force_loop_forward_nodes,
|
EdgeWeight weight_upper_bound,
|
||||||
const std::vector<NodeID> &force_loop_reverse_nodes,
|
const Args &...args)
|
||||||
EdgeWeight weight_upper_bound,
|
|
||||||
const Args &... args)
|
|
||||||
{
|
{
|
||||||
if (forward_heap.Empty() || reverse_heap.Empty())
|
if (forward_heap.Empty() || reverse_heap.Empty())
|
||||||
{
|
{
|
||||||
return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>());
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &partition = facade.GetMultiLevelPartition();
|
|
||||||
|
|
||||||
BOOST_ASSERT(!forward_heap.Empty() && forward_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
BOOST_ASSERT(!forward_heap.Empty() && forward_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
||||||
BOOST_ASSERT(!reverse_heap.Empty() && reverse_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
BOOST_ASSERT(!reverse_heap.Empty() && reverse_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
||||||
|
|
||||||
@@ -456,27 +515,15 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
{
|
{
|
||||||
if (!forward_heap.Empty())
|
if (!forward_heap.Empty())
|
||||||
{
|
{
|
||||||
routingStep<FORWARD_DIRECTION>(facade,
|
routingStep<FORWARD_DIRECTION>(
|
||||||
forward_heap,
|
facade, forward_heap, reverse_heap, middle, weight, force_step_nodes, args...);
|
||||||
reverse_heap,
|
|
||||||
middle,
|
|
||||||
weight,
|
|
||||||
force_loop_forward_nodes,
|
|
||||||
force_loop_reverse_nodes,
|
|
||||||
args...);
|
|
||||||
if (!forward_heap.Empty())
|
if (!forward_heap.Empty())
|
||||||
forward_heap_min = forward_heap.MinKey();
|
forward_heap_min = forward_heap.MinKey();
|
||||||
}
|
}
|
||||||
if (!reverse_heap.Empty())
|
if (!reverse_heap.Empty())
|
||||||
{
|
{
|
||||||
routingStep<REVERSE_DIRECTION>(facade,
|
routingStep<REVERSE_DIRECTION>(
|
||||||
reverse_heap,
|
facade, reverse_heap, forward_heap, middle, weight, force_step_nodes, args...);
|
||||||
forward_heap,
|
|
||||||
middle,
|
|
||||||
weight,
|
|
||||||
force_loop_reverse_nodes,
|
|
||||||
force_loop_forward_nodes,
|
|
||||||
args...);
|
|
||||||
if (!reverse_heap.Empty())
|
if (!reverse_heap.Empty())
|
||||||
reverse_heap_min = reverse_heap.MinKey();
|
reverse_heap_min = reverse_heap.MinKey();
|
||||||
}
|
}
|
||||||
@@ -484,10 +531,33 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
|
|
||||||
// No path found for both target nodes?
|
// No path found for both target nodes?
|
||||||
if (weight >= weight_upper_bound || SPECIAL_NODEID == middle)
|
if (weight >= weight_upper_bound || SPECIAL_NODEID == middle)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {{middle, weight}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Algorithm, typename... Args>
|
||||||
|
UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
||||||
|
const DataFacade<Algorithm> &facade,
|
||||||
|
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
||||||
|
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
||||||
|
const std::vector<NodeID> &force_step_nodes,
|
||||||
|
EdgeWeight weight_upper_bound,
|
||||||
|
const Args &...args)
|
||||||
|
{
|
||||||
|
auto searchResult = runSearch(
|
||||||
|
facade, forward_heap, reverse_heap, force_step_nodes, weight_upper_bound, args...);
|
||||||
|
if (!searchResult)
|
||||||
{
|
{
|
||||||
return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>());
|
return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto [middle, weight] = *searchResult;
|
||||||
|
|
||||||
|
const auto &partition = facade.GetMultiLevelPartition();
|
||||||
|
|
||||||
// Get packed path as edges {from node ID, to node ID, from_clique_arc}
|
// Get packed path as edges {from node ID, to node ID, from_clique_arc}
|
||||||
auto packed_path = retrievePackedPathFromHeap(forward_heap, reverse_heap, middle);
|
auto packed_path = retrievePackedPathFromHeap(forward_heap, reverse_heap, middle);
|
||||||
|
|
||||||
@@ -505,9 +575,7 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
|
|
||||||
for (auto const &packed_edge : packed_path)
|
for (auto const &packed_edge : packed_path)
|
||||||
{
|
{
|
||||||
NodeID source, target;
|
auto [source, target, overlay_edge] = packed_edge;
|
||||||
bool overlay_edge;
|
|
||||||
std::tie(source, target, overlay_edge) = packed_edge;
|
|
||||||
if (!overlay_edge)
|
if (!overlay_edge)
|
||||||
{ // a base graph edge
|
{ // a base graph edge
|
||||||
unpacked_nodes.push_back(target);
|
unpacked_nodes.push_back(target);
|
||||||
@@ -527,21 +595,14 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
forward_heap.Insert(source, {0}, {source});
|
forward_heap.Insert(source, {0}, {source});
|
||||||
reverse_heap.Insert(target, {0}, {target});
|
reverse_heap.Insert(target, {0}, {target});
|
||||||
|
|
||||||
// TODO: when structured bindings will be allowed change to
|
auto [subpath_weight, subpath_nodes, subpath_edges] = search(engine_working_data,
|
||||||
// auto [subpath_weight, subpath_source, subpath_target, subpath] = ...
|
facade,
|
||||||
EdgeWeight subpath_weight;
|
forward_heap,
|
||||||
std::vector<NodeID> subpath_nodes;
|
reverse_heap,
|
||||||
std::vector<EdgeID> subpath_edges;
|
force_step_nodes,
|
||||||
std::tie(subpath_weight, subpath_nodes, subpath_edges) =
|
INVALID_EDGE_WEIGHT,
|
||||||
search(engine_working_data,
|
sublevel,
|
||||||
facade,
|
parent_cell_id);
|
||||||
forward_heap,
|
|
||||||
reverse_heap,
|
|
||||||
force_loop_forward_nodes,
|
|
||||||
force_loop_reverse_nodes,
|
|
||||||
INVALID_EDGE_WEIGHT,
|
|
||||||
sublevel,
|
|
||||||
parent_cell_id);
|
|
||||||
BOOST_ASSERT(!subpath_edges.empty());
|
BOOST_ASSERT(!subpath_edges.empty());
|
||||||
BOOST_ASSERT(subpath_nodes.size() > 1);
|
BOOST_ASSERT(subpath_nodes.size() > 1);
|
||||||
BOOST_ASSERT(subpath_nodes.front() == source);
|
BOOST_ASSERT(subpath_nodes.front() == source);
|
||||||
@@ -555,6 +616,31 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
return std::make_tuple(weight, std::move(unpacked_nodes), std::move(unpacked_edges));
|
return std::make_tuple(weight, std::move(unpacked_nodes), std::move(unpacked_edges));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Algorithm, typename... Args>
|
||||||
|
EdgeDistance
|
||||||
|
searchDistance(SearchEngineData<Algorithm> &,
|
||||||
|
const DataFacade<Algorithm> &facade,
|
||||||
|
typename SearchEngineData<Algorithm>::MapMatchingQueryHeap &forward_heap,
|
||||||
|
typename SearchEngineData<Algorithm>::MapMatchingQueryHeap &reverse_heap,
|
||||||
|
const std::vector<NodeID> &force_step_nodes,
|
||||||
|
EdgeWeight weight_upper_bound,
|
||||||
|
const Args &...args)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto searchResult = runSearch(
|
||||||
|
facade, forward_heap, reverse_heap, force_step_nodes, weight_upper_bound, args...);
|
||||||
|
if (!searchResult)
|
||||||
|
{
|
||||||
|
return INVALID_EDGE_DISTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto [middle, _] = *searchResult;
|
||||||
|
|
||||||
|
auto distance = forward_heap.GetData(middle).distance + reverse_heap.GetData(middle).distance;
|
||||||
|
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
// Alias to be compatible with the CH-based search
|
// Alias to be compatible with the CH-based search
|
||||||
template <typename Algorithm, typename PhantomEndpointT>
|
template <typename Algorithm, typename PhantomEndpointT>
|
||||||
inline void search(SearchEngineData<Algorithm> &engine_working_data,
|
inline void search(SearchEngineData<Algorithm> &engine_working_data,
|
||||||
@@ -563,8 +649,7 @@ inline void search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
||||||
EdgeWeight &weight,
|
EdgeWeight &weight,
|
||||||
std::vector<NodeID> &unpacked_nodes,
|
std::vector<NodeID> &unpacked_nodes,
|
||||||
const std::vector<NodeID> &force_loop_forward_node,
|
const std::vector<NodeID> &force_step_nodes,
|
||||||
const std::vector<NodeID> &force_loop_reverse_node,
|
|
||||||
const PhantomEndpointT &endpoints,
|
const PhantomEndpointT &endpoints,
|
||||||
const EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
|
const EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
|
||||||
{
|
{
|
||||||
@@ -573,8 +658,7 @@ inline void search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
facade,
|
facade,
|
||||||
forward_heap,
|
forward_heap,
|
||||||
reverse_heap,
|
reverse_heap,
|
||||||
force_loop_forward_node,
|
force_step_nodes,
|
||||||
force_loop_reverse_node,
|
|
||||||
weight_upper_bound,
|
weight_upper_bound,
|
||||||
endpoints);
|
endpoints);
|
||||||
}
|
}
|
||||||
@@ -601,7 +685,8 @@ void unpackPath(const FacadeT &facade,
|
|||||||
util::for_each_pair(
|
util::for_each_pair(
|
||||||
packed_path_begin,
|
packed_path_begin,
|
||||||
packed_path_end,
|
packed_path_end,
|
||||||
[&facade, &unpacked_nodes, &unpacked_edges](const auto from, const auto to) {
|
[&facade, &unpacked_nodes, &unpacked_edges](const auto from, const auto to)
|
||||||
|
{
|
||||||
unpacked_nodes.push_back(to);
|
unpacked_nodes.push_back(to);
|
||||||
unpacked_edges.push_back(facade.FindEdge(from, to));
|
unpacked_edges.push_back(facade.FindEdge(from, to));
|
||||||
});
|
});
|
||||||
@@ -613,8 +698,8 @@ void unpackPath(const FacadeT &facade,
|
|||||||
template <typename Algorithm>
|
template <typename Algorithm>
|
||||||
double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
||||||
const DataFacade<Algorithm> &facade,
|
const DataFacade<Algorithm> &facade,
|
||||||
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
typename SearchEngineData<Algorithm>::MapMatchingQueryHeap &forward_heap,
|
||||||
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
typename SearchEngineData<Algorithm>::MapMatchingQueryHeap &reverse_heap,
|
||||||
const PhantomNode &source_phantom,
|
const PhantomNode &source_phantom,
|
||||||
const PhantomNode &target_phantom,
|
const PhantomNode &target_phantom,
|
||||||
EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
|
EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
|
||||||
@@ -622,31 +707,50 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
forward_heap.Clear();
|
forward_heap.Clear();
|
||||||
reverse_heap.Clear();
|
reverse_heap.Clear();
|
||||||
|
|
||||||
|
if (source_phantom.IsValidForwardSource())
|
||||||
|
{
|
||||||
|
forward_heap.Insert(source_phantom.forward_segment_id.id,
|
||||||
|
EdgeWeight{0} - source_phantom.GetForwardWeightPlusOffset(),
|
||||||
|
{source_phantom.forward_segment_id.id,
|
||||||
|
false,
|
||||||
|
EdgeDistance{0} - source_phantom.GetForwardDistance()});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source_phantom.IsValidReverseSource())
|
||||||
|
{
|
||||||
|
forward_heap.Insert(source_phantom.reverse_segment_id.id,
|
||||||
|
EdgeWeight{0} - source_phantom.GetReverseWeightPlusOffset(),
|
||||||
|
{source_phantom.reverse_segment_id.id,
|
||||||
|
false,
|
||||||
|
EdgeDistance{0} - source_phantom.GetReverseDistance()});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_phantom.IsValidForwardTarget())
|
||||||
|
{
|
||||||
|
reverse_heap.Insert(
|
||||||
|
target_phantom.forward_segment_id.id,
|
||||||
|
target_phantom.GetForwardWeightPlusOffset(),
|
||||||
|
{target_phantom.forward_segment_id.id, false, target_phantom.GetForwardDistance()});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_phantom.IsValidReverseTarget())
|
||||||
|
{
|
||||||
|
reverse_heap.Insert(
|
||||||
|
target_phantom.reverse_segment_id.id,
|
||||||
|
target_phantom.GetReverseWeightPlusOffset(),
|
||||||
|
{target_phantom.reverse_segment_id.id, false, target_phantom.GetReverseDistance()});
|
||||||
|
}
|
||||||
|
|
||||||
const PhantomEndpoints endpoints{source_phantom, target_phantom};
|
const PhantomEndpoints endpoints{source_phantom, target_phantom};
|
||||||
insertNodesInHeaps(forward_heap, reverse_heap, endpoints);
|
|
||||||
|
|
||||||
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
auto distance = searchDistance(
|
||||||
std::vector<NodeID> unpacked_nodes;
|
engine_working_data, facade, forward_heap, reverse_heap, {}, weight_upper_bound, endpoints);
|
||||||
std::vector<EdgeID> unpacked_edges;
|
|
||||||
std::tie(weight, unpacked_nodes, unpacked_edges) = search(engine_working_data,
|
|
||||||
facade,
|
|
||||||
forward_heap,
|
|
||||||
reverse_heap,
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
weight_upper_bound,
|
|
||||||
endpoints);
|
|
||||||
|
|
||||||
if (weight == INVALID_EDGE_WEIGHT)
|
if (distance == INVALID_EDGE_DISTANCE)
|
||||||
{
|
{
|
||||||
return std::numeric_limits<double>::max();
|
return std::numeric_limits<double>::max();
|
||||||
}
|
}
|
||||||
|
return from_alias<double>(distance);
|
||||||
std::vector<PathData> unpacked_path;
|
|
||||||
|
|
||||||
annotatePath(facade, endpoints, unpacked_nodes, unpacked_edges, unpacked_path);
|
|
||||||
|
|
||||||
return getPathDistance(facade, unpacked_path, source_phantom, target_phantom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace osrm::engine::routing_algorithms::mld
|
} // namespace osrm::engine::routing_algorithms::mld
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ void searchWithUTurn(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
||||||
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
|
||||||
const PhantomEndpointCandidates &candidates,
|
const PhantomEndpointCandidates &candidates,
|
||||||
const EdgeWeight &total_weight,
|
EdgeWeight &leg_weight,
|
||||||
EdgeWeight &new_total_weight,
|
|
||||||
std::vector<NodeID> &leg_packed_path)
|
std::vector<NodeID> &leg_packed_path)
|
||||||
{
|
{
|
||||||
forward_heap.Clear();
|
forward_heap.Clear();
|
||||||
@@ -31,14 +30,14 @@ void searchWithUTurn(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
if (source.IsValidForwardSource())
|
if (source.IsValidForwardSource())
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source.forward_segment_id.id,
|
forward_heap.Insert(source.forward_segment_id.id,
|
||||||
total_weight - source.GetForwardWeightPlusOffset(),
|
EdgeWeight{0} - source.GetForwardWeightPlusOffset(),
|
||||||
source.forward_segment_id.id);
|
source.forward_segment_id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source.IsValidReverseSource())
|
if (source.IsValidReverseSource())
|
||||||
{
|
{
|
||||||
forward_heap.Insert(source.reverse_segment_id.id,
|
forward_heap.Insert(source.reverse_segment_id.id,
|
||||||
total_weight - source.GetReverseWeightPlusOffset(),
|
EdgeWeight{0} - source.GetReverseWeightPlusOffset(),
|
||||||
source.reverse_segment_id.id);
|
source.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,10 +61,9 @@ void searchWithUTurn(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
facade,
|
facade,
|
||||||
forward_heap,
|
forward_heap,
|
||||||
reverse_heap,
|
reverse_heap,
|
||||||
new_total_weight,
|
leg_weight,
|
||||||
leg_packed_path,
|
leg_packed_path,
|
||||||
getForwardLoopNodes(candidates),
|
{},
|
||||||
getBackwardLoopNodes(candidates),
|
|
||||||
candidates);
|
candidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,8 +123,7 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
reverse_heap,
|
reverse_heap,
|
||||||
new_total_weight_to_forward,
|
new_total_weight_to_forward,
|
||||||
leg_packed_path_forward,
|
leg_packed_path_forward,
|
||||||
getForwardLoopNodes(candidates),
|
getForwardForceNodes(candidates),
|
||||||
{},
|
|
||||||
candidates);
|
candidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,8 +162,7 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
reverse_heap,
|
reverse_heap,
|
||||||
new_total_weight_to_reverse,
|
new_total_weight_to_reverse,
|
||||||
leg_packed_path_reverse,
|
leg_packed_path_reverse,
|
||||||
{},
|
getBackwardForceNodes(candidates),
|
||||||
getBackwardLoopNodes(candidates),
|
|
||||||
candidates);
|
candidates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,7 +244,8 @@ constructRouteResult(const DataFacade<Algorithm> &facade,
|
|||||||
auto source_it =
|
auto source_it =
|
||||||
std::find_if(source_candidates.begin(),
|
std::find_if(source_candidates.begin(),
|
||||||
source_candidates.end(),
|
source_candidates.end(),
|
||||||
[&start_node](const auto &source_phantom) {
|
[&start_node](const auto &source_phantom)
|
||||||
|
{
|
||||||
return (start_node == source_phantom.forward_segment_id.id ||
|
return (start_node == source_phantom.forward_segment_id.id ||
|
||||||
start_node == source_phantom.reverse_segment_id.id);
|
start_node == source_phantom.reverse_segment_id.id);
|
||||||
});
|
});
|
||||||
@@ -257,7 +254,8 @@ constructRouteResult(const DataFacade<Algorithm> &facade,
|
|||||||
auto target_it =
|
auto target_it =
|
||||||
std::find_if(target_candidates.begin(),
|
std::find_if(target_candidates.begin(),
|
||||||
target_candidates.end(),
|
target_candidates.end(),
|
||||||
[&end_node](const auto &target_phantom) {
|
[&end_node](const auto &target_phantom)
|
||||||
|
{
|
||||||
return (end_node == target_phantom.forward_segment_id.id ||
|
return (end_node == target_phantom.forward_segment_id.id ||
|
||||||
end_node == target_phantom.reverse_segment_id.id);
|
end_node == target_phantom.reverse_segment_id.id);
|
||||||
});
|
});
|
||||||
@@ -302,7 +300,7 @@ shortestPathWithWaypointUTurns(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
PhantomEndpointCandidates search_candidates{waypoint_candidates[i],
|
PhantomEndpointCandidates search_candidates{waypoint_candidates[i],
|
||||||
waypoint_candidates[i + 1]};
|
waypoint_candidates[i + 1]};
|
||||||
std::vector<NodeID> packed_leg;
|
std::vector<NodeID> packed_leg;
|
||||||
EdgeWeight new_total_weight = INVALID_EDGE_WEIGHT;
|
EdgeWeight leg_weight = INVALID_EDGE_WEIGHT;
|
||||||
|
|
||||||
// We have a valid path up to this leg
|
// We have a valid path up to this leg
|
||||||
BOOST_ASSERT(total_weight != INVALID_EDGE_WEIGHT);
|
BOOST_ASSERT(total_weight != INVALID_EDGE_WEIGHT);
|
||||||
@@ -311,16 +309,15 @@ shortestPathWithWaypointUTurns(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
forward_heap,
|
forward_heap,
|
||||||
reverse_heap,
|
reverse_heap,
|
||||||
search_candidates,
|
search_candidates,
|
||||||
total_weight,
|
leg_weight,
|
||||||
new_total_weight,
|
|
||||||
packed_leg);
|
packed_leg);
|
||||||
|
|
||||||
if (new_total_weight == INVALID_EDGE_WEIGHT)
|
if (leg_weight == INVALID_EDGE_WEIGHT)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
packed_leg_begin.push_back(total_packed_path.size());
|
packed_leg_begin.push_back(total_packed_path.size());
|
||||||
total_packed_path.insert(total_packed_path.end(), packed_leg.begin(), packed_leg.end());
|
total_packed_path.insert(total_packed_path.end(), packed_leg.begin(), packed_leg.end());
|
||||||
total_weight = new_total_weight;
|
total_weight += leg_weight;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add sentinel
|
// Add sentinel
|
||||||
@@ -466,16 +463,16 @@ struct route_state
|
|||||||
last.total_weight_to_forward.resize(init_candidates.size(), {0});
|
last.total_weight_to_forward.resize(init_candidates.size(), {0});
|
||||||
last.total_weight_to_reverse.resize(init_candidates.size(), {0});
|
last.total_weight_to_reverse.resize(init_candidates.size(), {0});
|
||||||
// Initialize routability from source validity.
|
// Initialize routability from source validity.
|
||||||
std::transform(
|
std::transform(init_candidates.begin(),
|
||||||
init_candidates.begin(),
|
init_candidates.end(),
|
||||||
init_candidates.end(),
|
std::back_inserter(last.reached_forward_node_target),
|
||||||
std::back_inserter(last.reached_forward_node_target),
|
[](const PhantomNode &phantom_node)
|
||||||
[](const PhantomNode &phantom_node) { return phantom_node.IsValidForwardSource(); });
|
{ return phantom_node.IsValidForwardSource(); });
|
||||||
std::transform(
|
std::transform(init_candidates.begin(),
|
||||||
init_candidates.begin(),
|
init_candidates.end(),
|
||||||
init_candidates.end(),
|
std::back_inserter(last.reached_reverse_node_target),
|
||||||
std::back_inserter(last.reached_reverse_node_target),
|
[](const PhantomNode &phantom_node)
|
||||||
[](const PhantomNode &phantom_node) { return phantom_node.IsValidReverseSource(); });
|
{ return phantom_node.IsValidReverseSource(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool completeLeg()
|
bool completeLeg()
|
||||||
@@ -613,15 +610,21 @@ struct route_state
|
|||||||
{
|
{
|
||||||
// Find the segment from final leg with the shortest path
|
// Find the segment from final leg with the shortest path
|
||||||
auto forward_range = util::irange<std::size_t>(0UL, last.total_weight_to_forward.size());
|
auto forward_range = util::irange<std::size_t>(0UL, last.total_weight_to_forward.size());
|
||||||
auto forward_min =
|
auto forward_min = std::min_element(
|
||||||
std::min_element(forward_range.begin(), forward_range.end(), [&](size_t a, size_t b) {
|
forward_range.begin(),
|
||||||
|
forward_range.end(),
|
||||||
|
[&](size_t a, size_t b)
|
||||||
|
{
|
||||||
return (last.total_weight_to_forward[a] < last.total_weight_to_forward[b] ||
|
return (last.total_weight_to_forward[a] < last.total_weight_to_forward[b] ||
|
||||||
(last.total_weight_to_forward[a] == last.total_weight_to_forward[b] &&
|
(last.total_weight_to_forward[a] == last.total_weight_to_forward[b] &&
|
||||||
last.total_nodes_to_forward[a] < last.total_nodes_to_forward[b]));
|
last.total_nodes_to_forward[a] < last.total_nodes_to_forward[b]));
|
||||||
});
|
});
|
||||||
auto reverse_range = util::irange<std::size_t>(0UL, last.total_weight_to_reverse.size());
|
auto reverse_range = util::irange<std::size_t>(0UL, last.total_weight_to_reverse.size());
|
||||||
auto reverse_min =
|
auto reverse_min = std::min_element(
|
||||||
std::min_element(reverse_range.begin(), reverse_range.end(), [&](size_t a, size_t b) {
|
reverse_range.begin(),
|
||||||
|
reverse_range.end(),
|
||||||
|
[&](size_t a, size_t b)
|
||||||
|
{
|
||||||
return (last.total_weight_to_reverse[a] < last.total_weight_to_reverse[b] ||
|
return (last.total_weight_to_reverse[a] < last.total_weight_to_reverse[b] ||
|
||||||
(last.total_weight_to_reverse[a] == last.total_weight_to_reverse[b] &&
|
(last.total_weight_to_reverse[a] == last.total_weight_to_reverse[b] &&
|
||||||
last.total_nodes_to_reverse[a] < last.total_nodes_to_reverse[b]));
|
last.total_nodes_to_reverse[a] < last.total_nodes_to_reverse[b]));
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ namespace osrm::engine
|
|||||||
|
|
||||||
// Algorithm-dependent heaps
|
// Algorithm-dependent heaps
|
||||||
// - CH algorithms use CH heaps
|
// - CH algorithms use CH heaps
|
||||||
// - CoreCH algorithms use CH
|
|
||||||
// - MLD algorithms use MLD heaps
|
// - MLD algorithms use MLD heaps
|
||||||
|
|
||||||
template <typename Algorithm> struct SearchEngineData
|
template <typename Algorithm> struct SearchEngineData
|
||||||
@@ -47,6 +46,7 @@ template <> struct SearchEngineData<routing_algorithms::ch::Algorithm>
|
|||||||
util::UnorderedMapStorage<NodeID, int>>;
|
util::UnorderedMapStorage<NodeID, int>>;
|
||||||
|
|
||||||
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
|
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
|
||||||
|
|
||||||
using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>;
|
using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>;
|
||||||
|
|
||||||
static SearchEngineHeapPtr forward_heap_1;
|
static SearchEngineHeapPtr forward_heap_1;
|
||||||
@@ -56,6 +56,10 @@ template <> struct SearchEngineData<routing_algorithms::ch::Algorithm>
|
|||||||
static SearchEngineHeapPtr forward_heap_3;
|
static SearchEngineHeapPtr forward_heap_3;
|
||||||
static SearchEngineHeapPtr reverse_heap_3;
|
static SearchEngineHeapPtr reverse_heap_3;
|
||||||
static ManyToManyHeapPtr many_to_many_heap;
|
static ManyToManyHeapPtr many_to_many_heap;
|
||||||
|
static SearchEngineHeapPtr map_matching_forward_heap_1;
|
||||||
|
static SearchEngineHeapPtr map_matching_reverse_heap_1;
|
||||||
|
|
||||||
|
void InitializeOrClearMapMatchingThreadLocalStorage(unsigned number_of_nodes);
|
||||||
|
|
||||||
void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes);
|
void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes);
|
||||||
|
|
||||||
@@ -74,6 +78,19 @@ struct MultiLayerDijkstraHeapData
|
|||||||
MultiLayerDijkstraHeapData(NodeID p, bool from) : parent(p), from_clique_arc(from) {}
|
MultiLayerDijkstraHeapData(NodeID p, bool from) : parent(p), from_clique_arc(from) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MapMatchingMultiLayerDijkstraHeapData
|
||||||
|
{
|
||||||
|
NodeID parent;
|
||||||
|
bool from_clique_arc;
|
||||||
|
EdgeDistance distance = {0};
|
||||||
|
MapMatchingMultiLayerDijkstraHeapData(NodeID p) : parent(p), from_clique_arc(false) {}
|
||||||
|
MapMatchingMultiLayerDijkstraHeapData(NodeID p, bool from) : parent(p), from_clique_arc(from) {}
|
||||||
|
MapMatchingMultiLayerDijkstraHeapData(NodeID p, bool from, EdgeDistance d)
|
||||||
|
: parent(p), from_clique_arc(from), distance(d)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData
|
struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData
|
||||||
{
|
{
|
||||||
EdgeDuration duration;
|
EdgeDuration duration;
|
||||||
@@ -104,16 +121,27 @@ template <> struct SearchEngineData<routing_algorithms::mld::Algorithm>
|
|||||||
EdgeWeight,
|
EdgeWeight,
|
||||||
ManyToManyMultiLayerDijkstraHeapData,
|
ManyToManyMultiLayerDijkstraHeapData,
|
||||||
util::TwoLevelStorage<NodeID, int>>;
|
util::TwoLevelStorage<NodeID, int>>;
|
||||||
|
using MapMatchingQueryHeap = util::QueryHeap<NodeID,
|
||||||
|
NodeID,
|
||||||
|
EdgeWeight,
|
||||||
|
MapMatchingMultiLayerDijkstraHeapData,
|
||||||
|
util::TwoLevelStorage<NodeID, int>>;
|
||||||
|
|
||||||
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
|
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
|
||||||
using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>;
|
using ManyToManyHeapPtr = boost::thread_specific_ptr<ManyToManyQueryHeap>;
|
||||||
|
using MapMatchingHeapPtr = boost::thread_specific_ptr<MapMatchingQueryHeap>;
|
||||||
|
|
||||||
static SearchEngineHeapPtr forward_heap_1;
|
static SearchEngineHeapPtr forward_heap_1;
|
||||||
static SearchEngineHeapPtr reverse_heap_1;
|
static SearchEngineHeapPtr reverse_heap_1;
|
||||||
|
static MapMatchingHeapPtr map_matching_forward_heap_1;
|
||||||
|
static MapMatchingHeapPtr map_matching_reverse_heap_1;
|
||||||
|
|
||||||
static ManyToManyHeapPtr many_to_many_heap;
|
static ManyToManyHeapPtr many_to_many_heap;
|
||||||
|
|
||||||
void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes,
|
void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes,
|
||||||
unsigned number_of_boundary_nodes);
|
unsigned number_of_boundary_nodes);
|
||||||
|
void InitializeOrClearMapMatchingThreadLocalStorage(unsigned number_of_nodes,
|
||||||
|
unsigned number_of_boundary_nodes);
|
||||||
|
|
||||||
void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes,
|
void InitializeOrClearManyToManyThreadLocalStorage(unsigned number_of_nodes,
|
||||||
unsigned number_of_boundary_nodes);
|
unsigned number_of_boundary_nodes);
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ inline auto getClassData(const std::size_t index)
|
|||||||
|
|
||||||
inline bool isValidClassName(const std::string &name)
|
inline bool isValidClassName(const std::string &name)
|
||||||
{
|
{
|
||||||
return std::find_if_not(name.begin(), name.end(), [](const auto c) {
|
return std::find_if_not(name.begin(),
|
||||||
return std::isalnum(c);
|
name.end(),
|
||||||
}) == name.end();
|
[](const auto c) { return std::isalnum(c); }) == name.end();
|
||||||
}
|
}
|
||||||
} // namespace osrm::extractor
|
} // namespace osrm::extractor
|
||||||
|
|
||||||
|
|||||||
@@ -125,9 +125,8 @@ inline std::string canonicalizeStringList(std::string strlist, const std::string
|
|||||||
|
|
||||||
// collapse spaces; this is needed in case we expand "; X" => "; X" above
|
// collapse spaces; this is needed in case we expand "; X" => "; X" above
|
||||||
// but also makes sense to do irregardless of the fact - canonicalizing strings.
|
// but also makes sense to do irregardless of the fact - canonicalizing strings.
|
||||||
const auto spaces = [](unsigned char lhs, unsigned char rhs) {
|
const auto spaces = [](unsigned char lhs, unsigned char rhs)
|
||||||
return ::isspace(lhs) && ::isspace(rhs);
|
{ return ::isspace(lhs) && ::isspace(rhs); };
|
||||||
};
|
|
||||||
auto it = std::unique(begin(strlist), end(strlist), spaces);
|
auto it = std::unique(begin(strlist), end(strlist), spaces);
|
||||||
strlist.erase(it, end(strlist));
|
strlist.erase(it, end(strlist));
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,8 @@ class ExtractionRelationContainer
|
|||||||
(void)res; // prevent unused warning in release
|
(void)res; // prevent unused warning in release
|
||||||
}
|
}
|
||||||
|
|
||||||
auto MergeRefMap = [&](RelationRefMap &source, RelationRefMap &target) {
|
auto MergeRefMap = [&](RelationRefMap &source, RelationRefMap &target)
|
||||||
|
{
|
||||||
for (auto it : source)
|
for (auto it : source)
|
||||||
{
|
{
|
||||||
auto &v = target[it.first];
|
auto &v = target[it.first];
|
||||||
@@ -151,7 +152,8 @@ class ExtractionRelationContainer
|
|||||||
const RelationIDList &GetRelations(const OsmIDTyped &member_id) const
|
const RelationIDList &GetRelations(const OsmIDTyped &member_id) const
|
||||||
{
|
{
|
||||||
auto getFromMap = [this](std::uint64_t id,
|
auto getFromMap = [this](std::uint64_t id,
|
||||||
const RelationRefMap &map) -> const RelationIDList & {
|
const RelationRefMap &map) -> const RelationIDList &
|
||||||
|
{
|
||||||
auto it = map.find(id);
|
auto it = map.find(id);
|
||||||
if (it != map.end())
|
if (it != map.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef OSRM_EXTRACTION_SEGMENT_HPP
|
#ifndef OSRM_EXTRACTION_SEGMENT_HPP
|
||||||
#define OSRM_EXTRACTION_SEGMENT_HPP
|
#define OSRM_EXTRACTION_SEGMENT_HPP
|
||||||
|
|
||||||
|
#include <extractor/node_based_edge.hpp>
|
||||||
#include <util/coordinate.hpp>
|
#include <util/coordinate.hpp>
|
||||||
|
|
||||||
namespace osrm::extractor
|
namespace osrm::extractor
|
||||||
@@ -12,9 +13,10 @@ struct ExtractionSegment
|
|||||||
const osrm::util::Coordinate target_,
|
const osrm::util::Coordinate target_,
|
||||||
double distance_,
|
double distance_,
|
||||||
double weight_,
|
double weight_,
|
||||||
double duration_)
|
double duration_,
|
||||||
|
const NodeBasedEdgeClassification flags_)
|
||||||
: source(source_), target(target_), distance(distance_), weight(weight_),
|
: source(source_), target(target_), distance(distance_), weight(weight_),
|
||||||
duration(duration_)
|
duration(duration_), flags(flags_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,6 +25,7 @@ struct ExtractionSegment
|
|||||||
const double distance;
|
const double distance;
|
||||||
double weight;
|
double weight;
|
||||||
double duration;
|
double duration;
|
||||||
|
const NodeBasedEdgeClassification flags;
|
||||||
};
|
};
|
||||||
} // namespace osrm::extractor
|
} // namespace osrm::extractor
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,9 @@
|
|||||||
|
|
||||||
#include "extractor/class_data.hpp"
|
#include "extractor/class_data.hpp"
|
||||||
#include "extractor/turn_lane_types.hpp"
|
#include "extractor/turn_lane_types.hpp"
|
||||||
|
#include "util/std_hash.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
#include <boost/functional/hash.hpp>
|
|
||||||
#include <boost/optional/optional_fwd.hpp>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
@@ -18,25 +16,6 @@ class Way;
|
|||||||
class Relation;
|
class Relation;
|
||||||
} // namespace osmium
|
} // namespace osmium
|
||||||
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
template <> struct hash<std::tuple<std::string, std::string, std::string, std::string, std::string>>
|
|
||||||
{
|
|
||||||
std::size_t operator()(
|
|
||||||
const std::tuple<std::string, std::string, std::string, std::string, std::string> &mk)
|
|
||||||
const noexcept
|
|
||||||
{
|
|
||||||
std::size_t seed = 0;
|
|
||||||
boost::hash_combine(seed, std::get<0>(mk));
|
|
||||||
boost::hash_combine(seed, std::get<1>(mk));
|
|
||||||
boost::hash_combine(seed, std::get<2>(mk));
|
|
||||||
boost::hash_combine(seed, std::get<3>(mk));
|
|
||||||
boost::hash_combine(seed, std::get<4>(mk));
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
namespace osrm::extractor
|
namespace osrm::extractor
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -28,13 +28,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef EXTRACTOR_CONFIG_HPP
|
#ifndef EXTRACTOR_CONFIG_HPP
|
||||||
#define EXTRACTOR_CONFIG_HPP
|
#define EXTRACTOR_CONFIG_HPP
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include "storage/io_config.hpp"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <filesystem>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "storage/io_config.hpp"
|
|
||||||
|
|
||||||
namespace osrm::extractor
|
namespace osrm::extractor
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -71,14 +70,14 @@ struct ExtractorConfig final : storage::IOConfig
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void UseDefaultOutputNames(const boost::filesystem::path &base)
|
void UseDefaultOutputNames(const std::filesystem::path &base)
|
||||||
{
|
{
|
||||||
IOConfig::UseDefaultOutputNames(base);
|
IOConfig::UseDefaultOutputNames(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path input_path;
|
std::filesystem::path input_path;
|
||||||
boost::filesystem::path profile_path;
|
std::filesystem::path profile_path;
|
||||||
std::vector<boost::filesystem::path> location_dependent_data_paths;
|
std::vector<std::filesystem::path> location_dependent_data_paths;
|
||||||
std::string data_version;
|
std::string data_version;
|
||||||
|
|
||||||
unsigned requested_num_threads = 0;
|
unsigned requested_num_threads = 0;
|
||||||
|
|||||||
+55
-58
@@ -23,9 +23,9 @@ namespace osrm::extractor::files
|
|||||||
|
|
||||||
// writes the .osrm.icd file
|
// writes the .osrm.icd file
|
||||||
template <typename IntersectionBearingsT, typename EntryClassVectorT>
|
template <typename IntersectionBearingsT, typename EntryClassVectorT>
|
||||||
inline void writeIntersections(const boost::filesystem::path &path,
|
void writeIntersections(const std::filesystem::path &path,
|
||||||
const IntersectionBearingsT &intersection_bearings,
|
const IntersectionBearingsT &intersection_bearings,
|
||||||
const EntryClassVectorT &entry_classes)
|
const EntryClassVectorT &entry_classes)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<IntersectionBearingsContainer, IntersectionBearingsT>::value ||
|
static_assert(std::is_same<IntersectionBearingsContainer, IntersectionBearingsT>::value ||
|
||||||
std::is_same<IntersectionBearingsView, IntersectionBearingsT>::value,
|
std::is_same<IntersectionBearingsView, IntersectionBearingsT>::value,
|
||||||
@@ -39,9 +39,9 @@ inline void writeIntersections(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// read the .osrm.icd file
|
// read the .osrm.icd file
|
||||||
template <typename IntersectionBearingsT, typename EntryClassVectorT>
|
template <typename IntersectionBearingsT, typename EntryClassVectorT>
|
||||||
inline void readIntersections(const boost::filesystem::path &path,
|
void readIntersections(const std::filesystem::path &path,
|
||||||
IntersectionBearingsT &intersection_bearings,
|
IntersectionBearingsT &intersection_bearings,
|
||||||
EntryClassVectorT &entry_classes)
|
EntryClassVectorT &entry_classes)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<IntersectionBearingsContainer, IntersectionBearingsT>::value ||
|
static_assert(std::is_same<IntersectionBearingsContainer, IntersectionBearingsT>::value ||
|
||||||
std::is_same<IntersectionBearingsView, IntersectionBearingsT>::value,
|
std::is_same<IntersectionBearingsView, IntersectionBearingsT>::value,
|
||||||
@@ -54,8 +54,7 @@ inline void readIntersections(const boost::filesystem::path &path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reads .osrm.properties
|
// reads .osrm.properties
|
||||||
inline void readProfileProperties(const boost::filesystem::path &path,
|
inline void readProfileProperties(const std::filesystem::path &path, ProfileProperties &properties)
|
||||||
ProfileProperties &properties)
|
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
storage::tar::FileReader reader{path, fingerprint};
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
@@ -64,7 +63,7 @@ inline void readProfileProperties(const boost::filesystem::path &path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// writes .osrm.properties
|
// writes .osrm.properties
|
||||||
inline void writeProfileProperties(const boost::filesystem::path &path,
|
inline void writeProfileProperties(const std::filesystem::path &path,
|
||||||
const ProfileProperties &properties)
|
const ProfileProperties &properties)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
@@ -74,7 +73,7 @@ inline void writeProfileProperties(const boost::filesystem::path &path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename EdgeBasedEdgeVector>
|
template <typename EdgeBasedEdgeVector>
|
||||||
void writeEdgeBasedGraph(const boost::filesystem::path &path,
|
void writeEdgeBasedGraph(const std::filesystem::path &path,
|
||||||
EdgeID const number_of_edge_based_nodes,
|
EdgeID const number_of_edge_based_nodes,
|
||||||
const EdgeBasedEdgeVector &edge_based_edge_list,
|
const EdgeBasedEdgeVector &edge_based_edge_list,
|
||||||
const std::uint32_t connectivity_checksum)
|
const std::uint32_t connectivity_checksum)
|
||||||
@@ -92,7 +91,7 @@ void writeEdgeBasedGraph(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// reads .osrm.ebg file
|
// reads .osrm.ebg file
|
||||||
template <typename EdgeBasedEdgeVector>
|
template <typename EdgeBasedEdgeVector>
|
||||||
void readEdgeBasedGraph(const boost::filesystem::path &path,
|
void readEdgeBasedGraph(const std::filesystem::path &path,
|
||||||
EdgeID &number_of_edge_based_nodes,
|
EdgeID &number_of_edge_based_nodes,
|
||||||
EdgeBasedEdgeVector &edge_based_edge_list,
|
EdgeBasedEdgeVector &edge_based_edge_list,
|
||||||
std::uint32_t &connectivity_checksum)
|
std::uint32_t &connectivity_checksum)
|
||||||
@@ -108,9 +107,9 @@ void readEdgeBasedGraph(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// reads .osrm.nbg_nodes
|
// reads .osrm.nbg_nodes
|
||||||
template <typename CoordinatesT, typename PackedOSMIDsT>
|
template <typename CoordinatesT, typename PackedOSMIDsT>
|
||||||
inline void readNodes(const boost::filesystem::path &path,
|
void readNodes(const std::filesystem::path &path,
|
||||||
CoordinatesT &coordinates,
|
CoordinatesT &coordinates,
|
||||||
PackedOSMIDsT &osm_node_ids)
|
PackedOSMIDsT &osm_node_ids)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<typename CoordinatesT::value_type, util::Coordinate>::value, "");
|
static_assert(std::is_same<typename CoordinatesT::value_type, util::Coordinate>::value, "");
|
||||||
static_assert(std::is_same<typename PackedOSMIDsT::value_type, OSMNodeID>::value, "");
|
static_assert(std::is_same<typename PackedOSMIDsT::value_type, OSMNodeID>::value, "");
|
||||||
@@ -124,7 +123,7 @@ inline void readNodes(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// reads only coordinates from .osrm.nbg_nodes
|
// reads only coordinates from .osrm.nbg_nodes
|
||||||
template <typename CoordinatesT>
|
template <typename CoordinatesT>
|
||||||
inline void readNodeCoordinates(const boost::filesystem::path &path, CoordinatesT &coordinates)
|
void readNodeCoordinates(const std::filesystem::path &path, CoordinatesT &coordinates)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<typename CoordinatesT::value_type, util::Coordinate>::value, "");
|
static_assert(std::is_same<typename CoordinatesT::value_type, util::Coordinate>::value, "");
|
||||||
|
|
||||||
@@ -136,9 +135,9 @@ inline void readNodeCoordinates(const boost::filesystem::path &path, Coordinates
|
|||||||
|
|
||||||
// writes .osrm.nbg_nodes
|
// writes .osrm.nbg_nodes
|
||||||
template <typename CoordinatesT, typename PackedOSMIDsT>
|
template <typename CoordinatesT, typename PackedOSMIDsT>
|
||||||
inline void writeNodes(const boost::filesystem::path &path,
|
void writeNodes(const std::filesystem::path &path,
|
||||||
const CoordinatesT &coordinates,
|
const CoordinatesT &coordinates,
|
||||||
const PackedOSMIDsT &osm_node_ids)
|
const PackedOSMIDsT &osm_node_ids)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<typename CoordinatesT::value_type, util::Coordinate>::value, "");
|
static_assert(std::is_same<typename CoordinatesT::value_type, util::Coordinate>::value, "");
|
||||||
static_assert(std::is_same<typename PackedOSMIDsT::value_type, OSMNodeID>::value, "");
|
static_assert(std::is_same<typename PackedOSMIDsT::value_type, OSMNodeID>::value, "");
|
||||||
@@ -151,7 +150,7 @@ inline void writeNodes(const boost::filesystem::path &path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reads .osrm.cnbg_to_ebg
|
// reads .osrm.cnbg_to_ebg
|
||||||
inline void readNBGMapping(const boost::filesystem::path &path, std::vector<NBGToEBG> &mapping)
|
inline void readNBGMapping(const std::filesystem::path &path, std::vector<NBGToEBG> &mapping)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
storage::tar::FileReader reader{path, fingerprint};
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
@@ -160,8 +159,7 @@ inline void readNBGMapping(const boost::filesystem::path &path, std::vector<NBGT
|
|||||||
}
|
}
|
||||||
|
|
||||||
// writes .osrm.cnbg_to_ebg
|
// writes .osrm.cnbg_to_ebg
|
||||||
inline void writeNBGMapping(const boost::filesystem::path &path,
|
inline void writeNBGMapping(const std::filesystem::path &path, const std::vector<NBGToEBG> &mapping)
|
||||||
const std::vector<NBGToEBG> &mapping)
|
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
storage::tar::FileWriter writer{path, fingerprint};
|
storage::tar::FileWriter writer{path, fingerprint};
|
||||||
@@ -170,7 +168,7 @@ inline void writeNBGMapping(const boost::filesystem::path &path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reads .osrm.datasource_names
|
// reads .osrm.datasource_names
|
||||||
inline void readDatasources(const boost::filesystem::path &path, Datasources &sources)
|
inline void readDatasources(const std::filesystem::path &path, Datasources &sources)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
storage::tar::FileReader reader{path, fingerprint};
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
@@ -179,7 +177,7 @@ inline void readDatasources(const boost::filesystem::path &path, Datasources &so
|
|||||||
}
|
}
|
||||||
|
|
||||||
// writes .osrm.datasource_names
|
// writes .osrm.datasource_names
|
||||||
inline void writeDatasources(const boost::filesystem::path &path, Datasources &sources)
|
inline void writeDatasources(const std::filesystem::path &path, Datasources &sources)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
storage::tar::FileWriter writer{path, fingerprint};
|
storage::tar::FileWriter writer{path, fingerprint};
|
||||||
@@ -189,7 +187,7 @@ inline void writeDatasources(const boost::filesystem::path &path, Datasources &s
|
|||||||
|
|
||||||
// reads .osrm.geometry
|
// reads .osrm.geometry
|
||||||
template <typename SegmentDataT>
|
template <typename SegmentDataT>
|
||||||
inline void readSegmentData(const boost::filesystem::path &path, SegmentDataT &segment_data)
|
void readSegmentData(const std::filesystem::path &path, SegmentDataT &segment_data)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<SegmentDataContainer, SegmentDataT>::value ||
|
static_assert(std::is_same<SegmentDataContainer, SegmentDataT>::value ||
|
||||||
std::is_same<SegmentDataView, SegmentDataT>::value,
|
std::is_same<SegmentDataView, SegmentDataT>::value,
|
||||||
@@ -202,7 +200,7 @@ inline void readSegmentData(const boost::filesystem::path &path, SegmentDataT &s
|
|||||||
|
|
||||||
// writes .osrm.geometry
|
// writes .osrm.geometry
|
||||||
template <typename SegmentDataT>
|
template <typename SegmentDataT>
|
||||||
inline void writeSegmentData(const boost::filesystem::path &path, const SegmentDataT &segment_data)
|
void writeSegmentData(const std::filesystem::path &path, const SegmentDataT &segment_data)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<SegmentDataContainer, SegmentDataT>::value ||
|
static_assert(std::is_same<SegmentDataContainer, SegmentDataT>::value ||
|
||||||
std::is_same<SegmentDataView, SegmentDataT>::value,
|
std::is_same<SegmentDataView, SegmentDataT>::value,
|
||||||
@@ -215,7 +213,7 @@ inline void writeSegmentData(const boost::filesystem::path &path, const SegmentD
|
|||||||
|
|
||||||
// reads .osrm.ebg_nodes
|
// reads .osrm.ebg_nodes
|
||||||
template <typename NodeDataT>
|
template <typename NodeDataT>
|
||||||
inline void readNodeData(const boost::filesystem::path &path, NodeDataT &node_data)
|
inline void readNodeData(const std::filesystem::path &path, NodeDataT &node_data)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<EdgeBasedNodeDataContainer, NodeDataT>::value ||
|
static_assert(std::is_same<EdgeBasedNodeDataContainer, NodeDataT>::value ||
|
||||||
std::is_same<EdgeBasedNodeDataView, NodeDataT>::value ||
|
std::is_same<EdgeBasedNodeDataView, NodeDataT>::value ||
|
||||||
@@ -229,7 +227,7 @@ inline void readNodeData(const boost::filesystem::path &path, NodeDataT &node_da
|
|||||||
|
|
||||||
// writes .osrm.ebg_nodes
|
// writes .osrm.ebg_nodes
|
||||||
template <typename NodeDataT>
|
template <typename NodeDataT>
|
||||||
inline void writeNodeData(const boost::filesystem::path &path, const NodeDataT &node_data)
|
inline void writeNodeData(const std::filesystem::path &path, const NodeDataT &node_data)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<EdgeBasedNodeDataContainer, NodeDataT>::value ||
|
static_assert(std::is_same<EdgeBasedNodeDataContainer, NodeDataT>::value ||
|
||||||
std::is_same<EdgeBasedNodeDataView, NodeDataT>::value ||
|
std::is_same<EdgeBasedNodeDataView, NodeDataT>::value ||
|
||||||
@@ -243,7 +241,7 @@ inline void writeNodeData(const boost::filesystem::path &path, const NodeDataT &
|
|||||||
|
|
||||||
// reads .osrm.tls
|
// reads .osrm.tls
|
||||||
template <typename OffsetsT, typename MaskT>
|
template <typename OffsetsT, typename MaskT>
|
||||||
inline void readTurnLaneDescriptions(const boost::filesystem::path &path,
|
inline void readTurnLaneDescriptions(const std::filesystem::path &path,
|
||||||
OffsetsT &turn_offsets,
|
OffsetsT &turn_offsets,
|
||||||
MaskT &turn_masks)
|
MaskT &turn_masks)
|
||||||
{
|
{
|
||||||
@@ -260,7 +258,7 @@ inline void readTurnLaneDescriptions(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// writes .osrm.tls
|
// writes .osrm.tls
|
||||||
template <typename OffsetsT, typename MaskT>
|
template <typename OffsetsT, typename MaskT>
|
||||||
inline void writeTurnLaneDescriptions(const boost::filesystem::path &path,
|
inline void writeTurnLaneDescriptions(const std::filesystem::path &path,
|
||||||
const OffsetsT &turn_offsets,
|
const OffsetsT &turn_offsets,
|
||||||
const MaskT &turn_masks)
|
const MaskT &turn_masks)
|
||||||
{
|
{
|
||||||
@@ -277,7 +275,7 @@ inline void writeTurnLaneDescriptions(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// reads .osrm.tld
|
// reads .osrm.tld
|
||||||
template <typename TurnLaneDataT>
|
template <typename TurnLaneDataT>
|
||||||
inline void readTurnLaneData(const boost::filesystem::path &path, TurnLaneDataT &turn_lane_data)
|
inline void readTurnLaneData(const std::filesystem::path &path, TurnLaneDataT &turn_lane_data)
|
||||||
{
|
{
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_same<typename TurnLaneDataT::value_type, util::guidance::LaneTupleIdPair>::value,
|
std::is_same<typename TurnLaneDataT::value_type, util::guidance::LaneTupleIdPair>::value,
|
||||||
@@ -291,7 +289,7 @@ inline void readTurnLaneData(const boost::filesystem::path &path, TurnLaneDataT
|
|||||||
|
|
||||||
// writes .osrm.tld
|
// writes .osrm.tld
|
||||||
template <typename TurnLaneDataT>
|
template <typename TurnLaneDataT>
|
||||||
inline void writeTurnLaneData(const boost::filesystem::path &path,
|
inline void writeTurnLaneData(const std::filesystem::path &path,
|
||||||
const TurnLaneDataT &turn_lane_data)
|
const TurnLaneDataT &turn_lane_data)
|
||||||
{
|
{
|
||||||
static_assert(
|
static_assert(
|
||||||
@@ -306,7 +304,7 @@ inline void writeTurnLaneData(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// reads .osrm.timestamp
|
// reads .osrm.timestamp
|
||||||
template <typename TimestampDataT>
|
template <typename TimestampDataT>
|
||||||
inline void readTimestamp(const boost::filesystem::path &path, TimestampDataT ×tamp)
|
inline void readTimestamp(const std::filesystem::path &path, TimestampDataT ×tamp)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
storage::tar::FileReader reader{path, fingerprint};
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
@@ -316,7 +314,7 @@ inline void readTimestamp(const boost::filesystem::path &path, TimestampDataT &t
|
|||||||
|
|
||||||
// writes .osrm.timestamp
|
// writes .osrm.timestamp
|
||||||
template <typename TimestampDataT>
|
template <typename TimestampDataT>
|
||||||
inline void writeTimestamp(const boost::filesystem::path &path, const TimestampDataT ×tamp)
|
inline void writeTimestamp(const std::filesystem::path &path, const TimestampDataT ×tamp)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
storage::tar::FileWriter writer{path, fingerprint};
|
storage::tar::FileWriter writer{path, fingerprint};
|
||||||
@@ -326,7 +324,7 @@ inline void writeTimestamp(const boost::filesystem::path &path, const TimestampD
|
|||||||
|
|
||||||
// reads .osrm.maneuver_overrides
|
// reads .osrm.maneuver_overrides
|
||||||
template <typename StorageManeuverOverrideT, typename NodeSequencesT>
|
template <typename StorageManeuverOverrideT, typename NodeSequencesT>
|
||||||
inline void readManeuverOverrides(const boost::filesystem::path &path,
|
inline void readManeuverOverrides(const std::filesystem::path &path,
|
||||||
StorageManeuverOverrideT &maneuver_overrides,
|
StorageManeuverOverrideT &maneuver_overrides,
|
||||||
NodeSequencesT &node_sequences)
|
NodeSequencesT &node_sequences)
|
||||||
{
|
{
|
||||||
@@ -340,7 +338,7 @@ inline void readManeuverOverrides(const boost::filesystem::path &path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// writes .osrm.maneuver_overrides
|
// writes .osrm.maneuver_overrides
|
||||||
inline void writeManeuverOverrides(const boost::filesystem::path &path,
|
inline void writeManeuverOverrides(const std::filesystem::path &path,
|
||||||
const std::vector<StorageManeuverOverride> &maneuver_overrides,
|
const std::vector<StorageManeuverOverride> &maneuver_overrides,
|
||||||
const std::vector<NodeID> &node_sequences)
|
const std::vector<NodeID> &node_sequences)
|
||||||
{
|
{
|
||||||
@@ -355,7 +353,7 @@ inline void writeManeuverOverrides(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// writes .osrm.turn_weight_penalties
|
// writes .osrm.turn_weight_penalties
|
||||||
template <typename TurnPenaltyT>
|
template <typename TurnPenaltyT>
|
||||||
inline void writeTurnWeightPenalty(const boost::filesystem::path &path,
|
inline void writeTurnWeightPenalty(const std::filesystem::path &path,
|
||||||
const TurnPenaltyT &turn_penalty)
|
const TurnPenaltyT &turn_penalty)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
@@ -366,7 +364,7 @@ inline void writeTurnWeightPenalty(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// read .osrm.turn_weight_penalties
|
// read .osrm.turn_weight_penalties
|
||||||
template <typename TurnPenaltyT>
|
template <typename TurnPenaltyT>
|
||||||
inline void readTurnWeightPenalty(const boost::filesystem::path &path, TurnPenaltyT &turn_penalty)
|
inline void readTurnWeightPenalty(const std::filesystem::path &path, TurnPenaltyT &turn_penalty)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
storage::tar::FileReader reader{path, fingerprint};
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
@@ -376,7 +374,7 @@ inline void readTurnWeightPenalty(const boost::filesystem::path &path, TurnPenal
|
|||||||
|
|
||||||
// writes .osrm.turn_duration_penalties
|
// writes .osrm.turn_duration_penalties
|
||||||
template <typename TurnPenaltyT>
|
template <typename TurnPenaltyT>
|
||||||
inline void writeTurnDurationPenalty(const boost::filesystem::path &path,
|
inline void writeTurnDurationPenalty(const std::filesystem::path &path,
|
||||||
const TurnPenaltyT &turn_penalty)
|
const TurnPenaltyT &turn_penalty)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
@@ -387,7 +385,7 @@ inline void writeTurnDurationPenalty(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// read .osrm.turn_weight_penalties
|
// read .osrm.turn_weight_penalties
|
||||||
template <typename TurnPenaltyT>
|
template <typename TurnPenaltyT>
|
||||||
inline void readTurnDurationPenalty(const boost::filesystem::path &path, TurnPenaltyT &turn_penalty)
|
inline void readTurnDurationPenalty(const std::filesystem::path &path, TurnPenaltyT &turn_penalty)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
storage::tar::FileReader reader{path, fingerprint};
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
@@ -397,7 +395,7 @@ inline void readTurnDurationPenalty(const boost::filesystem::path &path, TurnPen
|
|||||||
|
|
||||||
// writes .osrm.turn_penalties_index
|
// writes .osrm.turn_penalties_index
|
||||||
template <typename TurnIndexT>
|
template <typename TurnIndexT>
|
||||||
inline void writeTurnPenaltiesIndex(const boost::filesystem::path &path,
|
inline void writeTurnPenaltiesIndex(const std::filesystem::path &path,
|
||||||
const TurnIndexT &turn_penalties_index)
|
const TurnIndexT &turn_penalties_index)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
@@ -408,7 +406,7 @@ inline void writeTurnPenaltiesIndex(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// read .osrm.turn_penalties_index
|
// read .osrm.turn_penalties_index
|
||||||
template <typename TurnIndexT>
|
template <typename TurnIndexT>
|
||||||
inline void readTurnPenaltiesIndex(const boost::filesystem::path &path,
|
inline void readTurnPenaltiesIndex(const std::filesystem::path &path,
|
||||||
TurnIndexT &turn_penalties_index)
|
TurnIndexT &turn_penalties_index)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
@@ -419,7 +417,7 @@ inline void readTurnPenaltiesIndex(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// writes .osrm.restrictions
|
// writes .osrm.restrictions
|
||||||
template <typename ConditionalRestrictionsT>
|
template <typename ConditionalRestrictionsT>
|
||||||
inline void writeConditionalRestrictions(const boost::filesystem::path &path,
|
inline void writeConditionalRestrictions(const std::filesystem::path &path,
|
||||||
const ConditionalRestrictionsT &conditional_restrictions)
|
const ConditionalRestrictionsT &conditional_restrictions)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
@@ -430,7 +428,7 @@ inline void writeConditionalRestrictions(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// read .osrm.restrictions
|
// read .osrm.restrictions
|
||||||
template <typename ConditionalRestrictionsT>
|
template <typename ConditionalRestrictionsT>
|
||||||
inline void readConditionalRestrictions(const boost::filesystem::path &path,
|
inline void readConditionalRestrictions(const std::filesystem::path &path,
|
||||||
ConditionalRestrictionsT &conditional_restrictions)
|
ConditionalRestrictionsT &conditional_restrictions)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
@@ -441,7 +439,7 @@ inline void readConditionalRestrictions(const boost::filesystem::path &path,
|
|||||||
|
|
||||||
// reads .osrm file which is a temporary file of osrm-extract
|
// reads .osrm file which is a temporary file of osrm-extract
|
||||||
template <typename PackedOSMIDsT>
|
template <typename PackedOSMIDsT>
|
||||||
void readRawNBGraph(const boost::filesystem::path &path,
|
void readRawNBGraph(const std::filesystem::path &path,
|
||||||
std::vector<util::Coordinate> &coordinates,
|
std::vector<util::Coordinate> &coordinates,
|
||||||
PackedOSMIDsT &osm_node_ids,
|
PackedOSMIDsT &osm_node_ids,
|
||||||
std::vector<extractor::NodeBasedEdge> &edge_list)
|
std::vector<extractor::NodeBasedEdge> &edge_list)
|
||||||
@@ -453,7 +451,8 @@ void readRawNBGraph(const boost::filesystem::path &path,
|
|||||||
coordinates.resize(number_of_nodes);
|
coordinates.resize(number_of_nodes);
|
||||||
osm_node_ids.reserve(number_of_nodes);
|
osm_node_ids.reserve(number_of_nodes);
|
||||||
auto index = 0;
|
auto index = 0;
|
||||||
auto decode = [&](const auto ¤t_node) {
|
auto decode = [&](const auto ¤t_node)
|
||||||
|
{
|
||||||
coordinates[index].lon = current_node.lon;
|
coordinates[index].lon = current_node.lon;
|
||||||
coordinates[index].lat = current_node.lat;
|
coordinates[index].lat = current_node.lat;
|
||||||
osm_node_ids.push_back(current_node.node_id);
|
osm_node_ids.push_back(current_node.node_id);
|
||||||
@@ -465,8 +464,7 @@ void readRawNBGraph(const boost::filesystem::path &path,
|
|||||||
storage::serialization::read(reader, "/extractor/edges", edge_list);
|
storage::serialization::read(reader, "/extractor/edges", edge_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename NameTableT>
|
template <typename NameTableT> void readNames(const std::filesystem::path &path, NameTableT &table)
|
||||||
void readNames(const boost::filesystem::path &path, NameTableT &table)
|
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
storage::tar::FileReader reader{path, fingerprint};
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
@@ -475,7 +473,7 @@ void readNames(const boost::filesystem::path &path, NameTableT &table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename NameTableT>
|
template <typename NameTableT>
|
||||||
void writeNames(const boost::filesystem::path &path, const NameTableT &table)
|
void writeNames(const std::filesystem::path &path, const NameTableT &table)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
storage::tar::FileWriter writer{path, fingerprint};
|
storage::tar::FileWriter writer{path, fingerprint};
|
||||||
@@ -484,7 +482,7 @@ void writeNames(const boost::filesystem::path &path, const NameTableT &table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeWeightsVectorT>
|
template <typename NodeWeightsVectorT>
|
||||||
void readEdgeBasedNodeWeights(const boost::filesystem::path &path, NodeWeightsVectorT &weights)
|
void readEdgeBasedNodeWeights(const std::filesystem::path &path, NodeWeightsVectorT &weights)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
storage::tar::FileReader reader{path, fingerprint};
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
@@ -493,8 +491,7 @@ void readEdgeBasedNodeWeights(const boost::filesystem::path &path, NodeWeightsVe
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeDistancesVectorT>
|
template <typename NodeDistancesVectorT>
|
||||||
void readEdgeBasedNodeDistances(const boost::filesystem::path &path,
|
void readEdgeBasedNodeDistances(const std::filesystem::path &path, NodeDistancesVectorT &distances)
|
||||||
NodeDistancesVectorT &distances)
|
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
storage::tar::FileReader reader{path, fingerprint};
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
@@ -503,7 +500,7 @@ void readEdgeBasedNodeDistances(const boost::filesystem::path &path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeWeightsVectorT, typename NodeDurationsVectorT, typename NodeDistancesVectorT>
|
template <typename NodeWeightsVectorT, typename NodeDurationsVectorT, typename NodeDistancesVectorT>
|
||||||
void writeEdgeBasedNodeWeightsDurationsDistances(const boost::filesystem::path &path,
|
void writeEdgeBasedNodeWeightsDurationsDistances(const std::filesystem::path &path,
|
||||||
const NodeWeightsVectorT &weights,
|
const NodeWeightsVectorT &weights,
|
||||||
const NodeDurationsVectorT &durations,
|
const NodeDurationsVectorT &durations,
|
||||||
const NodeDistancesVectorT &distances)
|
const NodeDistancesVectorT &distances)
|
||||||
@@ -517,7 +514,7 @@ void writeEdgeBasedNodeWeightsDurationsDistances(const boost::filesystem::path &
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeWeightsVectorT, typename NodeDurationsVectorT>
|
template <typename NodeWeightsVectorT, typename NodeDurationsVectorT>
|
||||||
void readEdgeBasedNodeWeightsDurations(const boost::filesystem::path &path,
|
void readEdgeBasedNodeWeightsDurations(const std::filesystem::path &path,
|
||||||
NodeWeightsVectorT &weights,
|
NodeWeightsVectorT &weights,
|
||||||
NodeDurationsVectorT &durations)
|
NodeDurationsVectorT &durations)
|
||||||
{
|
{
|
||||||
@@ -529,7 +526,7 @@ void readEdgeBasedNodeWeightsDurations(const boost::filesystem::path &path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeWeightsVectorT, typename NodeDurationsVectorT>
|
template <typename NodeWeightsVectorT, typename NodeDurationsVectorT>
|
||||||
void writeEdgeBasedNodeWeightsDurations(const boost::filesystem::path &path,
|
void writeEdgeBasedNodeWeightsDurations(const std::filesystem::path &path,
|
||||||
const NodeWeightsVectorT &weights,
|
const NodeWeightsVectorT &weights,
|
||||||
const NodeDurationsVectorT &durations)
|
const NodeDurationsVectorT &durations)
|
||||||
{
|
{
|
||||||
@@ -541,7 +538,7 @@ void writeEdgeBasedNodeWeightsDurations(const boost::filesystem::path &path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename RTreeT>
|
template <typename RTreeT>
|
||||||
void writeRamIndex(const boost::filesystem::path &path, const RTreeT &rtree)
|
void writeRamIndex(const std::filesystem::path &path, const RTreeT &rtree)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
storage::tar::FileWriter writer{path, fingerprint};
|
storage::tar::FileWriter writer{path, fingerprint};
|
||||||
@@ -549,7 +546,7 @@ void writeRamIndex(const boost::filesystem::path &path, const RTreeT &rtree)
|
|||||||
util::serialization::write(writer, "/common/rtree", rtree);
|
util::serialization::write(writer, "/common/rtree", rtree);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename RTreeT> void readRamIndex(const boost::filesystem::path &path, RTreeT &rtree)
|
template <typename RTreeT> void readRamIndex(const std::filesystem::path &path, RTreeT &rtree)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
storage::tar::FileReader reader{path, fingerprint};
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
@@ -558,7 +555,7 @@ template <typename RTreeT> void readRamIndex(const boost::filesystem::path &path
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename EdgeListT>
|
template <typename EdgeListT>
|
||||||
void writeCompressedNodeBasedGraph(const boost::filesystem::path &path, const EdgeListT &edge_list)
|
void writeCompressedNodeBasedGraph(const std::filesystem::path &path, const EdgeListT &edge_list)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint;
|
||||||
storage::tar::FileWriter writer{path, fingerprint};
|
storage::tar::FileWriter writer{path, fingerprint};
|
||||||
@@ -567,7 +564,7 @@ void writeCompressedNodeBasedGraph(const boost::filesystem::path &path, const Ed
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename EdgeListT>
|
template <typename EdgeListT>
|
||||||
void readCompressedNodeBasedGraph(const boost::filesystem::path &path, EdgeListT &edge_list)
|
void readCompressedNodeBasedGraph(const std::filesystem::path &path, EdgeListT &edge_list)
|
||||||
{
|
{
|
||||||
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
const auto fingerprint = storage::tar::FileReader::VerifyFingerprint;
|
||||||
storage::tar::FileReader reader{path, fingerprint};
|
storage::tar::FileReader reader{path, fingerprint};
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class GraphCompressor
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
void Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const TrafficSignals &traffic_signals,
|
TrafficSignals &traffic_signals,
|
||||||
ScriptingEnvironment &scripting_environment,
|
ScriptingEnvironment &scripting_environment,
|
||||||
std::vector<TurnRestriction> &turn_restrictions,
|
std::vector<TurnRestriction> &turn_restrictions,
|
||||||
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <mapbox/variant.hpp>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
namespace osrm::extractor
|
namespace osrm::extractor
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
#ifndef OSRM_EXTRACTOR_INTERSECTION_COORDINATE_EXTRACTOR_HPP_
|
#ifndef OSRM_EXTRACTOR_INTERSECTION_COORDINATE_EXTRACTOR_HPP_
|
||||||
#define OSRM_EXTRACTOR_INTERSECTION_COORDINATE_EXTRACTOR_HPP_
|
#define OSRM_EXTRACTOR_INTERSECTION_COORDINATE_EXTRACTOR_HPP_
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "extractor/compressed_edge_container.hpp"
|
#include "extractor/compressed_edge_container.hpp"
|
||||||
#include "extractor/query_node.hpp"
|
#include "extractor/query_node.hpp"
|
||||||
|
|
||||||
#include "util/attributes.hpp"
|
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
#include "util/node_based_graph.hpp"
|
#include "util/node_based_graph.hpp"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace osrm::extractor::intersection
|
namespace osrm::extractor::intersection
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -27,17 +26,16 @@ class CoordinateExtractor
|
|||||||
* Note: The segment between intersection and turn coordinate can be zero, if the OSM modelling
|
* Note: The segment between intersection and turn coordinate can be zero, if the OSM modelling
|
||||||
* is unfortunate. See https://github.com/Project-OSRM/osrm-backend/issues/3470
|
* is unfortunate. See https://github.com/Project-OSRM/osrm-backend/issues/3470
|
||||||
*/
|
*/
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] util::Coordinate
|
||||||
util::Coordinate GetCoordinateAlongRoad(const NodeID intersection_node,
|
GetCoordinateAlongRoad(const NodeID intersection_node,
|
||||||
const EdgeID turn_edge,
|
const EdgeID turn_edge,
|
||||||
const bool traversed_in_reverse,
|
const bool traversed_in_reverse,
|
||||||
const NodeID to_node,
|
const NodeID to_node,
|
||||||
const std::uint8_t number_of_in_lanes) const;
|
const std::uint8_t number_of_in_lanes) const;
|
||||||
|
|
||||||
// Given a set of precomputed coordinates, select the representative coordinate along the road
|
// Given a set of precomputed coordinates, select the representative coordinate along the road
|
||||||
// that best describes the turn
|
// that best describes the turn
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] util::Coordinate
|
||||||
util::Coordinate
|
|
||||||
ExtractRepresentativeCoordinate(const NodeID intersection_node,
|
ExtractRepresentativeCoordinate(const NodeID intersection_node,
|
||||||
const EdgeID turn_edge,
|
const EdgeID turn_edge,
|
||||||
const bool traversed_in_reverse,
|
const bool traversed_in_reverse,
|
||||||
@@ -47,7 +45,7 @@ class CoordinateExtractor
|
|||||||
|
|
||||||
// instead of finding only a single coordinate, we can also list all coordinates along a
|
// instead of finding only a single coordinate, we can also list all coordinates along a
|
||||||
// road.
|
// road.
|
||||||
OSRM_ATTR_WARN_UNUSED std::vector<util::Coordinate>
|
[[nodiscard]] std::vector<util::Coordinate>
|
||||||
GetCoordinatesAlongRoad(const NodeID intersection_node,
|
GetCoordinatesAlongRoad(const NodeID intersection_node,
|
||||||
const EdgeID turn_edge,
|
const EdgeID turn_edge,
|
||||||
const bool traversed_in_reverse,
|
const bool traversed_in_reverse,
|
||||||
@@ -55,20 +53,18 @@ class CoordinateExtractor
|
|||||||
|
|
||||||
// wrapper in case of normal forward edges (traversed_in_reverse = false, to_node =
|
// wrapper in case of normal forward edges (traversed_in_reverse = false, to_node =
|
||||||
// node_based_graph.GetTarget(turn_edge)
|
// node_based_graph.GetTarget(turn_edge)
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] std::vector<util::Coordinate>
|
||||||
std::vector<util::Coordinate> GetForwardCoordinatesAlongRoad(const NodeID from,
|
GetForwardCoordinatesAlongRoad(const NodeID from, const EdgeID turn_edge) const;
|
||||||
const EdgeID turn_edge) const;
|
|
||||||
|
|
||||||
// a less precise way to compute coordinates along a route. Due to the heavy interaction of
|
// a less precise way to compute coordinates along a route. Due to the heavy interaction of
|
||||||
// graph traversal and turn instructions, we often don't care for high precision. We only want
|
// graph traversal and turn instructions, we often don't care for high precision. We only want
|
||||||
// to check for available connections in order, or find (with room for error) the straightmost
|
// to check for available connections in order, or find (with room for error) the straightmost
|
||||||
// turn. This function will offer a bit more error potential but allow for much higher
|
// turn. This function will offer a bit more error potential but allow for much higher
|
||||||
// performance
|
// performance
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] util::Coordinate GetCoordinateCloseToTurn(const NodeID from_node,
|
||||||
util::Coordinate GetCoordinateCloseToTurn(const NodeID from_node,
|
const EdgeID turn_edge,
|
||||||
const EdgeID turn_edge,
|
const bool traversed_in_reverse,
|
||||||
const bool traversed_in_reverse,
|
const NodeID to_node) const;
|
||||||
const NodeID to_node) const;
|
|
||||||
|
|
||||||
/* When extracting the coordinates, we first extract all coordinates. We don't care about most
|
/* When extracting the coordinates, we first extract all coordinates. We don't care about most
|
||||||
* of them, though.
|
* of them, though.
|
||||||
@@ -90,22 +86,19 @@ class CoordinateExtractor
|
|||||||
* The optional length cache needs to store the accumulated distance up to the respective
|
* The optional length cache needs to store the accumulated distance up to the respective
|
||||||
* coordinate index [0,d(0,1),...]
|
* coordinate index [0,d(0,1),...]
|
||||||
*/
|
*/
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] std::vector<util::Coordinate>
|
||||||
std::vector<util::Coordinate>
|
|
||||||
TrimCoordinatesToLength(std::vector<util::Coordinate> coordinates,
|
TrimCoordinatesToLength(std::vector<util::Coordinate> coordinates,
|
||||||
const double desired_length,
|
const double desired_length,
|
||||||
const std::vector<double> &length_cache = {}) const;
|
const std::vector<double> &length_cache = {}) const;
|
||||||
|
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] std::vector<double>
|
||||||
std::vector<double> PrepareLengthCache(const std::vector<util::Coordinate> &coordinates,
|
PrepareLengthCache(const std::vector<util::Coordinate> &coordinates, const double limit) const;
|
||||||
const double limit) const;
|
|
||||||
|
|
||||||
/* when looking at a set of coordinates, this function allows trimming the vector to a smaller,
|
/* when looking at a set of coordinates, this function allows trimming the vector to a smaller,
|
||||||
* only containing coordinates up to a given distance along the path. The last coordinate might
|
* only containing coordinates up to a given distance along the path. The last coordinate might
|
||||||
* be interpolated
|
* be interpolated
|
||||||
*/
|
*/
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] std::vector<util::Coordinate>
|
||||||
std::vector<util::Coordinate>
|
|
||||||
TrimCoordinatesByLengthFront(std::vector<util::Coordinate> coordinates,
|
TrimCoordinatesByLengthFront(std::vector<util::Coordinate> coordinates,
|
||||||
const double desired_length) const;
|
const double desired_length) const;
|
||||||
|
|
||||||
@@ -130,10 +123,9 @@ class CoordinateExtractor
|
|||||||
*
|
*
|
||||||
* for fixpoint `b`, vector_base `d` and vector_head `e`
|
* for fixpoint `b`, vector_base `d` and vector_head `e`
|
||||||
*/
|
*/
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] util::Coordinate GetCorrectedCoordinate(const util::Coordinate fixpoint,
|
||||||
util::Coordinate GetCorrectedCoordinate(const util::Coordinate fixpoint,
|
const util::Coordinate vector_base,
|
||||||
const util::Coordinate vector_base,
|
const util::Coordinate vector_head) const;
|
||||||
const util::Coordinate vector_head) const;
|
|
||||||
|
|
||||||
/* generate a uniform vector of coordinates in same range distances
|
/* generate a uniform vector of coordinates in same range distances
|
||||||
*
|
*
|
||||||
@@ -143,8 +135,7 @@ class CoordinateExtractor
|
|||||||
* Into:
|
* Into:
|
||||||
* x -- x -- x -- x -- x - x
|
* x -- x -- x -- x -- x - x
|
||||||
*/
|
*/
|
||||||
OSRM_ATTR_WARN_UNUSED
|
[[nodiscard]] std::vector<util::Coordinate>
|
||||||
std::vector<util::Coordinate>
|
|
||||||
SampleCoordinates(const std::vector<util::Coordinate> &coordinates,
|
SampleCoordinates(const std::vector<util::Coordinate> &coordinates,
|
||||||
const double length,
|
const double length,
|
||||||
const double rate) const;
|
const double rate) const;
|
||||||
|
|||||||
@@ -26,16 +26,14 @@ namespace osrm::extractor::intersection
|
|||||||
|
|
||||||
inline auto makeCompareAngularDeviation(const double angle)
|
inline auto makeCompareAngularDeviation(const double angle)
|
||||||
{
|
{
|
||||||
return [angle](const auto &lhs, const auto &rhs) {
|
return [angle](const auto &lhs, const auto &rhs)
|
||||||
return util::angularDeviation(lhs.angle, angle) < util::angularDeviation(rhs.angle, angle);
|
{ return util::angularDeviation(lhs.angle, angle) < util::angularDeviation(rhs.angle, angle); };
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto makeExtractLanesForRoad(const util::NodeBasedDynamicGraph &node_based_graph)
|
inline auto makeExtractLanesForRoad(const util::NodeBasedDynamicGraph &node_based_graph)
|
||||||
{
|
{
|
||||||
return [&node_based_graph](const auto &road) {
|
return [&node_based_graph](const auto &road)
|
||||||
return node_based_graph.GetEdgeData(road.eid).road_classification.GetNumberOfLanes();
|
{ return node_based_graph.GetEdgeData(road.eid).road_classification.GetNumberOfLanes(); };
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When viewing an intersection from an incoming edge, we can transform a shape into a view which
|
// When viewing an intersection from an incoming edge, we can transform a shape into a view which
|
||||||
@@ -63,7 +61,10 @@ template <typename Self> struct EnableShapeOps
|
|||||||
auto FindClosestBearing(double base_bearing) const
|
auto FindClosestBearing(double base_bearing) const
|
||||||
{
|
{
|
||||||
return std::min_element(
|
return std::min_element(
|
||||||
self()->begin(), self()->end(), [base_bearing](const auto &lhs, const auto &rhs) {
|
self()->begin(),
|
||||||
|
self()->end(),
|
||||||
|
[base_bearing](const auto &lhs, const auto &rhs)
|
||||||
|
{
|
||||||
return util::angularDeviation(lhs.perceived_bearing, base_bearing) <
|
return util::angularDeviation(lhs.perceived_bearing, base_bearing) <
|
||||||
util::angularDeviation(rhs.perceived_bearing, base_bearing);
|
util::angularDeviation(rhs.perceived_bearing, base_bearing);
|
||||||
});
|
});
|
||||||
@@ -81,7 +82,8 @@ template <typename Self> struct EnableShapeOps
|
|||||||
BOOST_ASSERT(!self()->empty());
|
BOOST_ASSERT(!self()->empty());
|
||||||
auto initial = converter(self()->front());
|
auto initial = converter(self()->front());
|
||||||
|
|
||||||
const auto extract_maximal_value = [&initial, converter](const auto &road) {
|
const auto extract_maximal_value = [&initial, converter](const auto &road)
|
||||||
|
{
|
||||||
initial = std::max(initial, converter(road));
|
initial = std::max(initial, converter(road));
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -191,8 +193,10 @@ template <typename Self> struct EnableIntersectionOps
|
|||||||
auto findClosestTurn(const double angle, const UnaryPredicate filter) const
|
auto findClosestTurn(const double angle, const UnaryPredicate filter) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!self()->empty());
|
BOOST_ASSERT(!self()->empty());
|
||||||
const auto candidate =
|
const auto candidate = boost::range::min_element(
|
||||||
boost::range::min_element(*self(), [angle, &filter](const auto &lhs, const auto &rhs) {
|
*self(),
|
||||||
|
[angle, &filter](const auto &lhs, const auto &rhs)
|
||||||
|
{
|
||||||
const auto filtered_lhs = filter(lhs), filtered_rhs = filter(rhs);
|
const auto filtered_lhs = filter(lhs), filtered_rhs = filter(rhs);
|
||||||
const auto deviation_lhs = util::angularDeviation(lhs.angle, angle),
|
const auto deviation_lhs = util::angularDeviation(lhs.angle, angle),
|
||||||
deviation_rhs = util::angularDeviation(rhs.angle, angle);
|
deviation_rhs = util::angularDeviation(rhs.angle, angle);
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/optional.hpp>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace osrm::extractor::intersection
|
namespace osrm::extractor::intersection
|
||||||
@@ -42,10 +42,10 @@ class NodeBasedGraphWalker
|
|||||||
* selector not provinding any further edge to traverse)
|
* selector not provinding any further edge to traverse)
|
||||||
*/
|
*/
|
||||||
template <class accumulator_type, class selector_type>
|
template <class accumulator_type, class selector_type>
|
||||||
boost::optional<std::pair<NodeID, EdgeID>> TraverseRoad(NodeID starting_at_node_id,
|
std::optional<std::pair<NodeID, EdgeID>> TraverseRoad(NodeID starting_at_node_id,
|
||||||
EdgeID following_edge_id,
|
EdgeID following_edge_id,
|
||||||
accumulator_type &accumulator,
|
accumulator_type &accumulator,
|
||||||
const selector_type &selector) const;
|
const selector_type &selector) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph;
|
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||||
@@ -111,11 +111,11 @@ struct SelectRoadByNameOnlyChoiceAndStraightness
|
|||||||
* traversal. If no such edge is found, return {} is allowed. Usually you want to choose some
|
* traversal. If no such edge is found, return {} is allowed. Usually you want to choose some
|
||||||
* form of obious turn to follow.
|
* form of obious turn to follow.
|
||||||
*/
|
*/
|
||||||
boost::optional<EdgeID> operator()(const NodeID nid,
|
std::optional<EdgeID> operator()(const NodeID nid,
|
||||||
const EdgeID via_edge_id,
|
const EdgeID via_edge_id,
|
||||||
const IntersectionView &intersection,
|
const IntersectionView &intersection,
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container) const;
|
const EdgeBasedNodeDataContainer &node_data_container) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const NameID desired_name_id;
|
const NameID desired_name_id;
|
||||||
@@ -138,11 +138,11 @@ struct SelectStraightmostRoadByNameAndOnlyChoice
|
|||||||
* traversal. If no such edge is found, return {} is allowed. Usually you want to choose some
|
* traversal. If no such edge is found, return {} is allowed. Usually you want to choose some
|
||||||
* form of obious turn to follow.
|
* form of obious turn to follow.
|
||||||
*/
|
*/
|
||||||
boost::optional<EdgeID> operator()(const NodeID nid,
|
std::optional<EdgeID> operator()(const NodeID nid,
|
||||||
const EdgeID via_edge_id,
|
const EdgeID via_edge_id,
|
||||||
const IntersectionView &intersection,
|
const IntersectionView &intersection,
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
const EdgeBasedNodeDataContainer &node_data_container) const;
|
const EdgeBasedNodeDataContainer &node_data_container) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const NameID desired_name_id;
|
const NameID desired_name_id;
|
||||||
@@ -187,7 +187,7 @@ struct IntersectionFinderAccumulator
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class accumulator_type, class selector_type>
|
template <class accumulator_type, class selector_type>
|
||||||
boost::optional<std::pair<NodeID, EdgeID>>
|
std::optional<std::pair<NodeID, EdgeID>>
|
||||||
NodeBasedGraphWalker::TraverseRoad(NodeID current_node_id,
|
NodeBasedGraphWalker::TraverseRoad(NodeID current_node_id,
|
||||||
EdgeID current_edge_id,
|
EdgeID current_edge_id,
|
||||||
accumulator_type &accumulator,
|
accumulator_type &accumulator,
|
||||||
@@ -254,19 +254,19 @@ NodeBasedGraphWalker::TraverseRoad(NodeID current_node_id,
|
|||||||
|
|
||||||
struct SkipTrafficSignalBarrierRoadSelector
|
struct SkipTrafficSignalBarrierRoadSelector
|
||||||
{
|
{
|
||||||
boost::optional<EdgeID> operator()(const NodeID,
|
std::optional<EdgeID> operator()(const NodeID,
|
||||||
const EdgeID,
|
const EdgeID,
|
||||||
const IntersectionView &intersection,
|
const IntersectionView &intersection,
|
||||||
const util::NodeBasedDynamicGraph &,
|
const util::NodeBasedDynamicGraph &,
|
||||||
const EdgeBasedNodeDataContainer &) const
|
const EdgeBasedNodeDataContainer &) const
|
||||||
{
|
{
|
||||||
if (intersection.isTrafficSignalOrBarrier())
|
if (intersection.isTrafficSignalOrBarrier())
|
||||||
{
|
{
|
||||||
return boost::make_optional(intersection[1].eid);
|
return std::make_optional(intersection[1].eid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return boost::none;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user