Compare commits

..

22 Commits

Author SHA1 Message Date
Dennis Luxen 4968d7f9d9 Disable codecov.io upload run since it consistently fails 2024-05-05 16:40:21 +02:00
Dennis Luxen c26f0612d1 Fix typo 2024-05-05 15:24:56 +02:00
Dennis Luxen de41299eda Update CHANGELOG.md 2024-05-05 15:03:12 +02:00
Dennis Luxen c37bbfd07a Migrate GitHub actions from {16, 18} to {28, 20} 2024-05-05 15:01:41 +02:00
Dennis Luxen 0fd1fb2904 Update minimum NodeJS dependency to 18 2024-05-05 14:51:56 +02:00
Matthew Wigginton Bhagat-Conway 7ebd21f39e pass flags into process_segment (#6658)
* pass flags into process_segment

---------

Co-authored-by: Michael Bell <michael@mjjbell.com>
2024-04-06 09:27:42 +01:00
Michael Bell 8ef366e061 Add support for opposite approach request parameter (#6842)
* Added approach on the opposite side of the road.

* Additional test and docs coverage for opposite approach

---------

Co-authored-by: Aleksandrs Saveljevs <Aleksandrs.Saveljevs@gmail.com>
2024-04-03 19:59:15 +01:00
rezashokry 367933fc1a Fix manuever overrides finding bug (#6739)
* sort manuever overrides vector after partition

---------

Co-authored-by: rshokri <reza.shokri@tapsi.cab>
Co-authored-by: Michael Bell <michael@mjjbell.com>
2024-03-24 21:48:28 +00:00
Damiaan Twelker c28ba66039 Increment feature id in tile speed layer (#6726)
* actually increment feature id in tile speed layer

---------

Co-authored-by: Michael Bell <michael@mjjbell.com>
2024-03-24 21:23:36 +00:00
Michael Bell d0e3e2af23 Extract prerelease/build information from package semver (#6839)
* Extract prerelease/build information from package semver

Currently we only extract the major.minor.patch identifiers from
the semver label stored in package.json.

This leads to version information in executables incorrectly
reporting a release version is running on prereleases and special builds.

This commit is a quickfix to extract this information and report it
in version strings.

CMake regex parsing is not sophisticated enough to handle the full semver
regex, so we might need to explore other CMake modules if we want to
strictly parse the label.
2024-03-24 18:33:07 +00:00
martin 8526cc7d45 Replace deprecated std::is_pod (#6717)
* Replace deprecated std::is_pod
2024-03-17 11:49:55 +00:00
Trivikram Kamat 016440fc7e Remove unused AWS SDK for JavaScript v2 (#6730) 2024-03-17 11:37:51 +00:00
Monday 6e77d53946 Correctly handle compressed traffic signals (#6724)
Unidirectional traffic signal segments are currently not compressed.
This means traffic signals which are not on turns can be missed and
not applied the correct penalty.

This commit changes this behaviour to correctly handle the graph
compression. Additional tests are added to ensure there is no
regression for other cases (turns, restrictions).

Co-authored-by: Michael Bell <michael@mjjbell.com>
2024-03-17 11:32:10 +00:00
Frédéric Rodrigo 99875b4d24 Set Maxspeed for Philippines (#6776) 2024-03-16 11:35:25 +00:00
Michael Bell c315a586f7 Delete .github/ISSUE_TEMPLATE/question.md (#6827)
With Discussions now enabled, remove the question issue template to encourage Q&A interaction in the more appropriate place.
2024-03-15 09:35:09 +00:00
Daniel Spasojevic 69c38401bc Update osrm-backend-docker link to point to github hosted repo (#6831) 2024-03-15 10:29:39 +01:00
Michael Bell e219eb9442 Pin Conan revisions correctly (#6828)
* Pin Conan revisions correctly

Conan dependencies are not pinned correctly. This means we're
pulling in a newer onetbb recipe that no longer has a shared
library option.

Following other examples of how to pin revisions with cmake
for conan v1, we correctly pin the expected revisions.

Longer term we should look into
- upgrading to conan v2
- defining the conan config separately from cmakelists.txt
- understanding the need for disabling onetbb shared library support

but for the purposes of reviving CI, this will be sufficient.

* Fix macos CI builds
2024-03-15 09:27:59 +00:00
Daniel Patterson 31e31a63d0 Fix some compilation issues on modern macOS systems (#6709)
* Fix various compiler warnings generated by Apple clang 15, and workaround some boost 1.8 bugs

* Fix formatting.
2023-10-12 23:04:39 +02:00
danieldegroot2 b437ce5b33 Update debug_way.lua (#6713) 2023-10-12 23:03:35 +02:00
Frédéric Rodrigo 5723eaaa6a Added motorway speed limits for Bulgaria (original fix by pl71) (#6698) 2023-09-13 22:01:36 +02:00
Frédéric Rodrigo 0f7b86b099 Install data directory (geojson files) like the profiles directory (#6699) 2023-09-13 22:01:06 +02:00
fenwuyaoji 14dcf91812 add keepalive_timeout flag (#6674)
* add keepalive_timeout flag
2023-08-30 19:06:39 +01:00
88 changed files with 1569 additions and 5381 deletions
-5
View File
@@ -1,5 +0,0 @@
---
name: Question
about: Ask a question about OSRM
labels: question
---
+48 -67
View File
@@ -34,7 +34,7 @@ jobs:
- run: cmake --version - run: cmake --version
- uses: actions/setup-node@v3 - uses: actions/setup-node@v3
with: with:
node-version: 16 node-version: 18
- run: node --version - run: node --version
- run: npm --version - run: npm --version
- name: Prepare environment - name: Prepare environment
@@ -77,7 +77,7 @@ jobs:
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: 16 node-version: 18
- name: Enable Node.js cache - name: Enable Node.js cache
uses: actions/cache@v3 uses: actions/cache@v3
with: with:
@@ -97,29 +97,6 @@ jobs:
npm run docs && ./scripts/error_on_dirty.sh npm run docs && ./scripts/error_on_dirty.sh
npm audit --production npm audit --production
routed-js:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 14
- name: Enable Node.js cache
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Compile routed-js
run: |
pushd routed-js
npm ci
npx tsc
popd
./scripts/error_on_dirty.sh
docker-image: docker-image:
needs: format-taginfo-docs needs: format-taginfo-docs
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
@@ -170,7 +147,7 @@ jobs:
include: include:
- name: gcc-9-debug-cov - name: gcc-9-debug-cov
continue-on-error: false continue-on-error: false
node: 16 node: 18
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Debug BUILD_TYPE: Debug
@@ -181,7 +158,7 @@ jobs:
- name: gcc-9-debug-asan-ubsan - name: gcc-9-debug-asan-ubsan
continue-on-error: false continue-on-error: false
node: 16 node: 18
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Debug BUILD_TYPE: Debug
@@ -195,7 +172,7 @@ jobs:
- name: clang-6.0-debug - name: clang-6.0-debug
continue-on-error: false continue-on-error: false
node: 16 node: 18
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Debug BUILD_TYPE: Debug
@@ -205,7 +182,7 @@ jobs:
- name: clang-15.0-debug-clang-tidy - name: clang-15.0-debug-clang-tidy
continue-on-error: false continue-on-error: false
node: 16 node: 18
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Debug BUILD_TYPE: Debug
@@ -216,7 +193,7 @@ jobs:
- name: conan-linux-debug-asan-ubsan - name: conan-linux-debug-asan-ubsan
continue-on-error: false continue-on-error: false
node: 16 node: 18
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Release BUILD_TYPE: Release
@@ -227,7 +204,7 @@ jobs:
- name: conan-linux-release - name: conan-linux-release
continue-on-error: false continue-on-error: false
node: 16 node: 18
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Release BUILD_TYPE: Release
@@ -237,7 +214,7 @@ jobs:
- name: gcc-12-release - name: gcc-12-release
continue-on-error: false continue-on-error: false
node: 16 node: 18
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Release BUILD_TYPE: Release
@@ -248,7 +225,7 @@ jobs:
- name: gcc-11-release - name: gcc-11-release
continue-on-error: false continue-on-error: false
node: 16 node: 18
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Release BUILD_TYPE: Release
@@ -258,7 +235,7 @@ jobs:
- name: gcc-10-release - name: gcc-10-release
continue-on-error: false continue-on-error: false
node: 16 node: 18
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Release BUILD_TYPE: Release
@@ -267,7 +244,7 @@ jobs:
- name: gcc-9-release - name: gcc-9-release
continue-on-error: false continue-on-error: false
node: 16 node: 18
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Release BUILD_TYPE: Release
@@ -277,7 +254,7 @@ jobs:
- name: gcc-9-conan-release-i686 - name: gcc-9-conan-release-i686
continue-on-error: false continue-on-error: false
node: 16 node: 18
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Release BUILD_TYPE: Release
@@ -287,10 +264,10 @@ jobs:
CXXFLAGS: "-m32 -msse2 -mfpmath=sse" CXXFLAGS: "-m32 -msse2 -mfpmath=sse"
TARGET_ARCH: i686 TARGET_ARCH: i686
ENABLE_CONAN: ON ENABLE_CONAN: ON
- name: gcc-8-release - name: gcc-8-release
continue-on-error: false continue-on-error: false
node: 16 node: 18
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Release BUILD_TYPE: Release
@@ -301,7 +278,7 @@ jobs:
- name: conan-linux-release-node - name: conan-linux-release-node
build_node_package: true build_node_package: true
continue-on-error: false continue-on-error: false
node: 18 node: 20
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TYPE: Release BUILD_TYPE: Release
CCOMPILER: clang-6.0 CCOMPILER: clang-6.0
@@ -312,7 +289,7 @@ jobs:
- name: conan-linux-debug-node - name: conan-linux-debug-node
build_node_package: true build_node_package: true
continue-on-error: false continue-on-error: false
node: 18 node: 20
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
BUILD_TYPE: Debug BUILD_TYPE: Debug
CCOMPILER: clang-6.0 CCOMPILER: clang-6.0
@@ -323,7 +300,7 @@ jobs:
- name: conan-macos-x64-release-node - name: conan-macos-x64-release-node
build_node_package: true build_node_package: true
continue-on-error: true continue-on-error: true
node: 18 node: 20
runs-on: macos-11 runs-on: macos-11
BUILD_TYPE: Release BUILD_TYPE: Release
CCOMPILER: clang CCOMPILER: clang
@@ -335,7 +312,7 @@ jobs:
- name: conan-macos-arm64-release-node - name: conan-macos-arm64-release-node
build_node_package: true build_node_package: true
continue-on-error: true continue-on-error: true
node: 18 node: 20
runs-on: macos-11 runs-on: macos-11
BUILD_TYPE: Release BUILD_TYPE: Release
CCOMPILER: clang CCOMPILER: clang
@@ -392,9 +369,9 @@ jobs:
uses: actions/cache@v3 uses: actions/cache@v3
with: with:
path: ~/.conan path: ~/.conan
key: v6-conan-${{ matrix.name }}-${{ github.sha }} key: v7-conan-${{ matrix.name }}-${{ github.sha }}
restore-keys: | restore-keys: |
v6-conan-${{ matrix.name }}- v7-conan-${{ matrix.name }}-
- name: Enable test cache - name: Enable test cache
uses: actions/cache@v3 uses: actions/cache@v3
with: with:
@@ -485,6 +462,12 @@ jobs:
fi fi
echo "CC=${CCOMPILER}" >> $GITHUB_ENV echo "CC=${CCOMPILER}" >> $GITHUB_ENV
echo "CXX=${CXXCOMPILER}" >> $GITHUB_ENV echo "CXX=${CXXCOMPILER}" >> $GITHUB_ENV
if [[ "${RUNNER_OS}" == "macOS" ]]; then
# missing from GCC path, needed for conan builds of libiconv, for example.
sudo xcode-select --switch /Library/Developer/CommandLineTools
echo "LIBRARY_PATH=${LIBRARY_PATH}:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib" >> $GITHUB_ENV
echo "CPATH=${CPATH}:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include" >> $GITHUB_ENV
fi
- name: Build and install OSRM - name: Build and install OSRM
run: | run: |
@@ -535,9 +518,6 @@ jobs:
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
make --jobs=${JOBS} make --jobs=${JOBS}
popd popd
- name: Install osrm-routed-js dependencies
if: ${{ matrix.node != 12 && matrix.ENABLE_APPLE_SILICON != 'ON' && matrix.TARGET_ARCH != 'i686' }}
run: cd routed-js && npm ci && npm link && osrm-routed-js --version
- name: Run all tests - name: Run all tests
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY != 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }} if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY != 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
run: | run: |
@@ -567,16 +547,6 @@ jobs:
./src/benchmarks/rtree-bench ../test/data/monaco.osrm.ramIndex ../test/data/monaco.osrm.fileIndex ../test/data/monaco.osrm.nbg_nodes ./src/benchmarks/rtree-bench ../test/data/monaco.osrm.ramIndex ../test/data/monaco.osrm.fileIndex ../test/data/monaco.osrm.nbg_nodes
popd popd
- name: Use Node 16
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
uses: actions/setup-node@v3
with:
node-version: 16
- name: Run Node package tests on Node 16
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
run: |
node --version
npm run nodejs-tests
- name: Use Node 18 - name: Use Node 18
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }} if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
uses: actions/setup-node@v3 uses: actions/setup-node@v3
@@ -587,6 +557,16 @@ jobs:
run: | run: |
node --version node --version
npm run nodejs-tests npm run nodejs-tests
- name: Use Node 20
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
uses: actions/setup-node@v3
with:
node-version: 20
- name: Run Node package tests on Node 20
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
run: |
node --version
npm run nodejs-tests
- name: Use Node latest - name: Use Node latest
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }} if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
uses: actions/setup-node@v3 uses: actions/setup-node@v3
@@ -611,15 +591,16 @@ jobs:
lcov --directory . --capture --output-file coverage.info # capture coverage info lcov --directory . --capture --output-file coverage.info # capture coverage info
lcov --remove coverage.info '/usr/*' --output-file coverage.info # filter out system lcov --remove coverage.info '/usr/*' --output-file coverage.info # filter out system
lcov --list coverage.info #debug info lcov --list coverage.info #debug info
# Uploading report to CodeCov
- name: Upload code coverage # # Uploading report to CodeCov
if: ${{ matrix.ENABLE_COVERAGE == 'ON' }} # - name: Upload code coverage
uses: codecov/codecov-action@v1 # if: ${{ matrix.ENABLE_COVERAGE == 'ON' }}
with: # uses: codecov/codecov-action@v1
files: coverage.info # with:
name: codecov-osrm-backend # files: coverage.info
fail_ci_if_error: true # name: codecov-osrm-backend
verbose: true # fail_ci_if_error: true
# verbose: true
- name: Check Apple Silicon binary - name: Check Apple Silicon binary
if: ${{ matrix.ENABLE_APPLE_SILICON == 'ON' }} if: ${{ matrix.ENABLE_APPLE_SILICON == 'ON' }}
run: | run: |
@@ -648,6 +629,6 @@ jobs:
ci-complete: ci-complete:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
needs: [build-test-publish, docker-image, routed-js, windows-release-node] needs: [build-test-publish, docker-image, windows-release-node]
steps: steps:
- run: echo "CI complete" - run: echo "CI complete"
+10
View File
@@ -1,14 +1,18 @@
# Unreleased # Unreleased
- Changes from 5.27.1 - Changes from 5.27.1
- Features - Features
- 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:
- 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: Drop support for Node 16 [#6855](https://github.com/Project-OSRM/osrm-backend/pull/6855)
- 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:
@@ -30,10 +34,16 @@
- 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)
- 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:
+55 -36
View File
@@ -73,14 +73,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)
@@ -151,7 +154,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()
@@ -312,7 +315,7 @@ add_subdirectory(${FLATBUFFERS_SRC_DIR}
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-9.1.0/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,22 +325,24 @@ 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.79.0@#96e4902111a2e343a8ba0aa95391bb58")
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.2.10@#916908d4a570ad839edd25322c3268cd")
set(CONAN_LUA_VERSION "5.4.4@#3ec62efc37cd0a5d80b9e5cb35277360")
set(CONAN_TBB_VERSION "2021.3.0@#507ec17cbd51a84167e143b20d170eea")
set(CONAN_SYSTEM_INCLUDES ON) set(CONAN_SYSTEM_INCLUDES ON)
# TODO: # TODO:
# if we link TBB dynamically osrm-extract.exe finishes on the first access to any TBB symbol # 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. # with exit code = -1073741515, which means that program cannot load required DLL.
if (MSVC) if (MSVC)
set(TBB_SHARED False) set(TBB_SHARED False)
@@ -345,14 +350,14 @@ if(ENABLE_CONAN)
set(TBB_SHARED True) set(TBB_SHARED True)
endif() 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
@@ -361,6 +366,13 @@ if(ENABLE_CONAN)
boost:without_stacktrace=True # Apple Silicon cross-compilation fails without it 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")
@@ -389,7 +401,7 @@ if(ENABLE_CONAN)
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_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)
@@ -462,6 +474,9 @@ 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) 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})
@@ -639,6 +654,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 +752,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
View File
@@ -20,7 +20,7 @@ For a quick introduction about how the road network is represented in OpenStreet
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 -3
View File
@@ -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',
}; };
+2 -2
View File
@@ -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`. |
``` ```
+4 -4
View File
@@ -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)**
+162 -42
View File
@@ -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 |
+9 -14
View File
@@ -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));
} }
} }
+24
View File
@@ -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"
+3 -4
View File
@@ -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
-2
View File
@@ -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"
-5
View File
@@ -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);
+1 -3
View File
@@ -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,7 +41,7 @@ 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.0;
this.HOST = `http://${this.OSRM_IP}:${this.OSRM_PORT}`; this.HOST = `http://${this.OSRM_IP}:${this.OSRM_PORT}`;
-4
View File
@@ -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
+1 -1
View File
@@ -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 |
+362 -16
View File
@@ -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) |
+2 -2
View File
@@ -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 |
-1
View File
@@ -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"
+1 -3
View File
@@ -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
+2 -3
View File
@@ -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 |
+1 -2
View File
@@ -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 -6
View File
@@ -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
""" """
+5 -5
View File
@@ -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
-14
View File
@@ -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
+2 -1
View File
@@ -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
+2 -1
View File
@@ -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
+4 -1
View File
@@ -558,7 +558,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 +573,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);
+5 -2
View File
@@ -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
+1 -1
View File
@@ -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,
@@ -39,7 +39,7 @@ class NodeBasedGraphFactory
NodeBasedGraphFactory(ScriptingEnvironment &scripting_environment, NodeBasedGraphFactory(ScriptingEnvironment &scripting_environment,
std::vector<TurnRestriction> &turn_restrictions, std::vector<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &maneuver_overrides, std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
const TrafficSignals &traffic_signals, TrafficSignals &traffic_signals,
std::unordered_set<NodeID> &&barriers, std::unordered_set<NodeID> &&barriers,
std::vector<util::Coordinate> &&coordinates, std::vector<util::Coordinate> &&coordinates,
extractor::PackedOSMIDs &&osm_node_ids, extractor::PackedOSMIDs &&osm_node_ids,
@@ -71,7 +71,7 @@ class NodeBasedGraphFactory
void Compress(ScriptingEnvironment &scripting_environment, void Compress(ScriptingEnvironment &scripting_environment,
std::vector<TurnRestriction> &turn_restrictions, std::vector<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &maneuver_overrides, std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
const TrafficSignals &traffic_signals); TrafficSignals &traffic_signals);
// Most ways are bidirectional, making the geometry in forward and backward direction the same, // Most ways are bidirectional, making the geometry in forward and backward direction the same,
// except for reversal. We make use of this fact by keeping only one representation of the // except for reversal. We make use of this fact by keeping only one representation of the
+15
View File
@@ -19,6 +19,21 @@ struct TrafficSignals
{ {
return bidirectional_nodes.count(to) > 0 || unidirectional_segments.count({from, to}) > 0; return bidirectional_nodes.count(to) > 0 || unidirectional_segments.count({from, to}) > 0;
} }
void Compress(NodeID from, NodeID via, NodeID to)
{
bidirectional_nodes.erase(via);
if (unidirectional_segments.count({via, to}))
{
unidirectional_segments.erase({via, to});
unidirectional_segments.insert({from, to});
}
if (unidirectional_segments.count({via, from}))
{
unidirectional_segments.erase({via, from});
unidirectional_segments.insert({to, from});
}
}
}; };
} // namespace osrm::extractor } // namespace osrm::extractor
+8 -2
View File
@@ -99,6 +99,7 @@ inline void ParseResult(const osrm::Status &result_status, osrm::json::Object &r
throw std::logic_error(code_iter->second.get<osrm::json::String>().value.c_str()); throw std::logic_error(code_iter->second.get<osrm::json::String>().value.c_str());
} }
result.values.erase(code_iter);
const auto message_iter = result.values.find("message"); const auto message_iter = result.values.find("message");
if (message_iter != end_iter) if (message_iter != end_iter)
{ {
@@ -559,6 +560,10 @@ inline bool argumentsToParameter(const Napi::CallbackInfo &args,
{ {
params->approaches.push_back(osrm::Approach::CURB); params->approaches.push_back(osrm::Approach::CURB);
} }
else if (approach_str == "opposite")
{
params->approaches.push_back(osrm::Approach::OPPOSITE);
}
else if (approach_str == "unrestricted") else if (approach_str == "unrestricted")
{ {
params->approaches.push_back(osrm::Approach::UNRESTRICTED); params->approaches.push_back(osrm::Approach::UNRESTRICTED);
@@ -566,13 +571,14 @@ inline bool argumentsToParameter(const Napi::CallbackInfo &args,
else else
{ {
ThrowError(args.Env(), ThrowError(args.Env(),
"'approaches' param must be one of [curb, unrestricted]"); "'approaches' param must be one of [curb, opposite, unrestricted]");
return false; return false;
} }
} }
else else
{ {
ThrowError(args.Env(), "Approach must be a string: [curb, unrestricted] or null"); ThrowError(args.Env(),
"Approach must be a string: [curb, opposite, unrestricted] or null");
return false; return false;
} }
} }
@@ -166,8 +166,9 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
qi::lit("bearings=") > qi::lit("bearings=") >
(-(qi::short_ > ',' > qi::short_))[ph::bind(add_bearing, qi::_r1, qi::_1)] % ';'; (-(qi::short_ > ',' > qi::short_))[ph::bind(add_bearing, qi::_r1, qi::_1)] % ';';
approach_type.add("unrestricted", engine::Approach::UNRESTRICTED)("curb", approach_type.add("unrestricted", engine::Approach::UNRESTRICTED)(
engine::Approach::CURB); "curb", engine::Approach::CURB)("opposite", engine::Approach::OPPOSITE);
approach_rule = qi::lit("approaches=") > approach_rule = qi::lit("approaches=") >
(-approach_type % (-approach_type %
';')[ph::bind(&engine::api::BaseParameters::approaches, qi::_r1) = qi::_1]; ';')[ph::bind(&engine::api::BaseParameters::approaches, qi::_r1) = qi::_1];
+3 -1
View File
@@ -35,7 +35,9 @@ class RequestHandler;
class Connection : public std::enable_shared_from_this<Connection> class Connection : public std::enable_shared_from_this<Connection>
{ {
public: public:
explicit Connection(boost::asio::io_context &io_context, RequestHandler &handler); explicit Connection(boost::asio::io_context &io_context,
RequestHandler &handler,
short keepalive_timeout);
Connection(const Connection &) = delete; Connection(const Connection &) = delete;
Connection &operator=(const Connection &) = delete; Connection &operator=(const Connection &) = delete;
+15 -7
View File
@@ -31,18 +31,24 @@ class Server
{ {
public: public:
// Note: returns a shared instead of a unique ptr as it is captured in a lambda somewhere else // Note: returns a shared instead of a unique ptr as it is captured in a lambda somewhere else
static std::shared_ptr<Server> static std::shared_ptr<Server> CreateServer(std::string &ip_address,
CreateServer(std::string &ip_address, int ip_port, unsigned requested_num_threads) int ip_port,
unsigned requested_num_threads,
short keepalive_timeout)
{ {
util::Log() << "http 1.1 compression handled by zlib version " << zlibVersion(); util::Log() << "http 1.1 compression handled by zlib version " << zlibVersion();
const unsigned hardware_threads = std::max(1u, std::thread::hardware_concurrency()); const unsigned hardware_threads = std::max(1u, std::thread::hardware_concurrency());
const unsigned real_num_threads = std::min(hardware_threads, requested_num_threads); const unsigned real_num_threads = std::min(hardware_threads, requested_num_threads);
return std::make_shared<Server>(ip_address, ip_port, real_num_threads); return std::make_shared<Server>(ip_address, ip_port, real_num_threads, keepalive_timeout);
} }
explicit Server(const std::string &address, const int port, const unsigned thread_pool_size) explicit Server(const std::string &address,
: thread_pool_size(thread_pool_size), acceptor(io_context), const int port,
new_connection(std::make_shared<Connection>(io_context, request_handler)) const unsigned thread_pool_size,
const short keepalive_timeout)
: thread_pool_size(thread_pool_size), keepalive_timeout(keepalive_timeout),
acceptor(io_context), new_connection(std::make_shared<Connection>(
io_context, request_handler, keepalive_timeout))
{ {
const auto port_string = std::to_string(port); const auto port_string = std::to_string(port);
@@ -94,7 +100,8 @@ class Server
if (!e) if (!e)
{ {
new_connection->start(); new_connection->start();
new_connection = std::make_shared<Connection>(io_context, request_handler); new_connection =
std::make_shared<Connection>(io_context, request_handler, keepalive_timeout);
acceptor.async_accept( acceptor.async_accept(
new_connection->socket(), new_connection->socket(),
boost::bind(&Server::HandleAccept, this, boost::asio::placeholders::error)); boost::bind(&Server::HandleAccept, this, boost::asio::placeholders::error));
@@ -107,6 +114,7 @@ class Server
RequestHandler request_handler; RequestHandler request_handler;
unsigned thread_pool_size; unsigned thread_pool_size;
short keepalive_timeout;
boost::asio::io_context io_context; boost::asio::io_context io_context;
boost::asio::ip::tcp::acceptor acceptor; boost::asio::ip::tcp::acceptor acceptor;
std::shared_ptr<Connection> new_connection; std::shared_ptr<Connection> new_connection;
+14 -6
View File
@@ -72,12 +72,20 @@ using FloatLongitude = Alias<double, tag::longitude>;
// range checks on these (toFixed/toFloat, etc) // range checks on these (toFixed/toFloat, etc)
using UnsafeFloatLatitude = Alias<double, tag::unsafelatitude>; using UnsafeFloatLatitude = Alias<double, tag::unsafelatitude>;
using UnsafeFloatLongitude = Alias<double, tag::unsafelongitude>; using UnsafeFloatLongitude = Alias<double, tag::unsafelongitude>;
static_assert(std::is_pod<FixedLatitude>(), "FixedLatitude is not a valid alias"); static_assert(std::is_standard_layout<FixedLatitude>() && std::is_trivial<FixedLatitude>(),
static_assert(std::is_pod<FixedLongitude>(), "FixedLongitude is not a valid alias"); "FixedLatitude is not a valid alias");
static_assert(std::is_pod<FloatLatitude>(), "FloatLatitude is not a valid alias"); static_assert(std::is_standard_layout<FixedLongitude>() && std::is_trivial<FixedLongitude>(),
static_assert(std::is_pod<FloatLongitude>(), "FloatLongitude is not a valid alias"); "FixedLongitude is not a valid alias");
static_assert(std::is_pod<UnsafeFloatLatitude>(), "UnsafeFloatLatitude is not a valid alias"); static_assert(std::is_standard_layout<FloatLatitude>() && std::is_trivial<FloatLatitude>(),
static_assert(std::is_pod<UnsafeFloatLongitude>(), "UnsafeFloatLongitude is not a valid alias"); "FloatLatitude is not a valid alias");
static_assert(std::is_standard_layout<FloatLongitude>() && std::is_trivial<FloatLongitude>(),
"FloatLongitude is not a valid alias");
static_assert(std::is_standard_layout<UnsafeFloatLatitude>() &&
std::is_trivial<UnsafeFloatLatitude>(),
"UnsafeFloatLatitude is not a valid alias");
static_assert(std::is_standard_layout<UnsafeFloatLongitude>() &&
std::is_trivial<UnsafeFloatLongitude>(),
"UnsafeFloatLongitude is not a valid alias");
/** /**
* Converts a typed latitude from floating to fixed representation. * Converts a typed latitude from floating to fixed representation.
+4 -2
View File
@@ -184,7 +184,8 @@ double getLength(iterator_type begin, const iterator_type end, BinaryOperation o
return false; return false;
}; };
// side-effect find adding up distances // side-effect find adding up distances
std::adjacent_find(begin, end, functor); // Ignore return value, we are only interested in the side-effect
[[maybe_unused]] auto _ = std::adjacent_find(begin, end, functor);
return result; return result;
} }
@@ -202,7 +203,8 @@ findClosestDistance(const Coordinate coordinate, const iterator_type begin, cons
return false; return false;
}; };
std::adjacent_find(begin, end, compute_minimum_distance); // Ignore return value, we are only interested in the side-effect
[[maybe_unused]] auto _ = std::adjacent_find(begin, end, compute_minimum_distance);
return current_min; return current_min;
} }
+2 -1
View File
@@ -33,7 +33,8 @@ struct FingerPrint
static_assert(sizeof(FingerPrint) == 8, "FingerPrint has unexpected size"); static_assert(sizeof(FingerPrint) == 8, "FingerPrint has unexpected size");
static_assert(std::is_trivial<FingerPrint>::value, "FingerPrint needs to be trivial."); static_assert(std::is_trivial<FingerPrint>::value, "FingerPrint needs to be trivial.");
static_assert(std::is_pod<FingerPrint>::value, "FingerPrint needs to be a POD."); static_assert(std::is_standard_layout<FingerPrint>::value,
"FingerPrint needs have a standard layout.");
} // namespace osrm::util } // namespace osrm::util
#endif /* FingerPrint_H */ #endif /* FingerPrint_H */
+4 -2
View File
@@ -71,10 +71,12 @@ struct turn_penalty
using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>; using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>;
// clang-tidy fires `bugprone-throw-keyword-missing` here for unknown reason // clang-tidy fires `bugprone-throw-keyword-missing` here for unknown reason
// NOLINTNEXTLINE(bugprone-throw-keyword-missing) // NOLINTNEXTLINE(bugprone-throw-keyword-missing)
static_assert(std::is_pod<OSMNodeID>(), "OSMNodeID is not a valid alias"); static_assert(std::is_standard_layout<OSMNodeID>() && std::is_trivial<OSMNodeID>(),
"OSMNodeID is not a valid alias");
using OSMWayID = osrm::Alias<std::uint64_t, tag::osm_way_id>; using OSMWayID = osrm::Alias<std::uint64_t, tag::osm_way_id>;
// NOLINTNEXTLINE(bugprone-throw-keyword-missing) // NOLINTNEXTLINE(bugprone-throw-keyword-missing)
static_assert(std::is_pod<OSMWayID>(), "OSMWayID is not a valid alias"); static_assert(std::is_standard_layout<OSMWayID>() && std::is_trivial<OSMWayID>(),
"OSMWayID is not a valid alias");
using DuplicatedNodeID = std::uint64_t; using DuplicatedNodeID = std::uint64_t;
using RestrictionID = std::uint64_t; using RestrictionID = std::uint64_t;
+7 -6
View File
@@ -1,12 +1,13 @@
#ifndef VERSION_HPP #ifndef VERSION_HPP
#define VERSION_HPP #define VERSION_HPP
#define OSRM_VERSION_MAJOR @OSRM_VERSION_MAJOR@ #define OSRM_VERSION_MAJOR @OSRM_VERSION_MAJOR@
#define OSRM_VERSION_MINOR @OSRM_VERSION_MINOR@ #define OSRM_VERSION_MINOR @OSRM_VERSION_MINOR@
#define OSRM_VERSION_PATCH @OSRM_VERSION_PATCH@ #define OSRM_VERSION_PATCH @OSRM_VERSION_PATCH@
#define OSRM_VERSION_PRERELEASE_BUILD "@OSRM_VERSION_PRERELEASE_BUILD@"
#define OSRM_VERSION__(A,B,C) "v" #A "." #B "." #C #define OSRM_VERSION__(A,B,C,D) "v" #A "." #B "." #C D
#define OSRM_VERSION_(A,B,C) OSRM_VERSION__(A,B,C) #define OSRM_VERSION_(A,B,C,D) OSRM_VERSION__(A,B,C,D)
#define OSRM_VERSION OSRM_VERSION_(OSRM_VERSION_MAJOR, OSRM_VERSION_MINOR, OSRM_VERSION_PATCH) #define OSRM_VERSION OSRM_VERSION_(OSRM_VERSION_MAJOR, OSRM_VERSION_MINOR, OSRM_VERSION_PATCH, OSRM_VERSION_PRERELEASE_BUILD)
#endif // VERSION_HPP #endif // VERSION_HPP
+635 -633
View File
File diff suppressed because it is too large Load Diff
+2 -3
View File
@@ -4,7 +4,7 @@
"private": false, "private": false,
"description": "The Open Source Routing Machine is a high performance routing engine written in C++ designed to run on OpenStreetMap data.", "description": "The Open Source Routing Machine is a high performance routing engine written in C++ designed to run on OpenStreetMap data.",
"dependencies": { "dependencies": {
"@mapbox/node-pre-gyp": "^1.0.10" "@mapbox/node-pre-gyp": "^1.0.11"
}, },
"browserify": { "browserify": {
"transform": [ "transform": [
@@ -31,7 +31,7 @@
}, },
"homepage": "https://github.com/Project-OSRM/osrm-backend", "homepage": "https://github.com/Project-OSRM/osrm-backend",
"engines": { "engines": {
"node": ">=4.0.0" "node": ">=18.0.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.18.10", "@babel/cli": "^7.18.10",
@@ -40,7 +40,6 @@
"@babel/preset-react": "^7.18.6", "@babel/preset-react": "^7.18.6",
"acorn": "^8.8.0", "acorn": "^8.8.0",
"ansi-escape-sequences": "^5.1.2", "ansi-escape-sequences": "^5.1.2",
"aws-sdk": "~2.0.31",
"babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-class-properties": "^6.24.1",
"babelify": "^10.0.0", "babelify": "^10.0.0",
"browserify": "^17.0.0", "browserify": "^17.0.0",
+4
View File
@@ -274,6 +274,7 @@ function setup()
["be-bru:rural"] = 70, ["be-bru:rural"] = 70,
["be-bru:urban"] = 30, ["be-bru:urban"] = 30,
["be-vlg:rural"] = 70, ["be-vlg:rural"] = 70,
["bg:motorway"] = 140,
["by:urban"] = 60, ["by:urban"] = 60,
["by:motorway"] = 110, ["by:motorway"] = 110,
["ca-on:rural"] = 80, ["ca-on:rural"] = 80,
@@ -295,6 +296,9 @@ function setup()
["nl:trunk"] = 100, ["nl:trunk"] = 100,
['no:rural'] = 80, ['no:rural'] = 80,
['no:motorway'] = 110, ['no:motorway'] = 110,
['ph:urban'] = 40,
['ph:rural'] = 80,
['ph:motorway'] = 100,
['pl:rural'] = 100, ['pl:rural'] = 100,
['pl:trunk'] = 120, ['pl:trunk'] = 120,
['pl:motorway'] = 140, ['pl:motorway'] = 140,
+1 -1
View File
@@ -21,7 +21,7 @@ local https = require('ssl.https')
Debug.load_profile(arg[1]) Debug.load_profile(arg[1])
-- load way from the OSM API -- load way from the OSM API
local url = 'https://www.openstreetmap.org/api/0.6/way/'..arg[2] local url = 'https://api.openstreetmap.org/api/0.6/way/'..arg[2]
local body, statusCode, headers, statusText = https.request(url) local body, statusCode, headers, statusText = https.request(url)
-- parse way tags -- parse way tags
-8
View File
@@ -1,8 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Format = void 0;
var Format;
(function (Format) {
Format["Json"] = "json";
Format["Flatbuffers"] = "flatbuffers";
})(Format = exports.Format || (exports.Format = {}));
-4
View File
@@ -1,4 +0,0 @@
export enum Format {
Json = 'json',
Flatbuffers = 'flatbuffers'
}
-25
View File
@@ -1,25 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MatchServiceHandler = void 0;
const ServiceHandler_1 = require("./ServiceHandler");
class MatchServiceHandler extends ServiceHandler_1.ServiceHandler {
buildServiceOptions(options, query) {
if (query.timestamps) {
options.timestamps = query.timestamps;
}
if (query.waypoints) {
options.waypoints = query.waypoints;
}
if (query.gaps) {
options.gaps = query.gaps;
}
if (query.tidy) {
options.tidy = query.tidy;
}
return options;
}
async callOSRM(options) {
return this.osrm.match(options);
}
}
exports.MatchServiceHandler = MatchServiceHandler;
-27
View File
@@ -1,27 +0,0 @@
import { ServiceHandler } from './ServiceHandler';
export class MatchServiceHandler extends ServiceHandler {
protected buildServiceOptions(options: any, query: any): any {
if (query.timestamps) {
options.timestamps = query.timestamps;
}
if (query.waypoints) {
options.waypoints = query.waypoints;
}
if (query.gaps) {
options.gaps = query.gaps;
}
if (query.tidy) {
options.tidy = query.tidy;
}
return options;
}
protected async callOSRM(options: any): Promise<any> {
return this.osrm.match(options);
}
}
-16
View File
@@ -1,16 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NearestServiceHandler = void 0;
const ServiceHandler_1 = require("./ServiceHandler");
class NearestServiceHandler extends ServiceHandler_1.ServiceHandler {
buildServiceOptions(options, query) {
if (query.number !== undefined) {
options.number = query.number;
}
return options;
}
async callOSRM(options) {
return this.osrm.nearest(options);
}
}
exports.NearestServiceHandler = NearestServiceHandler;
-14
View File
@@ -1,14 +0,0 @@
import { ServiceHandler } from './ServiceHandler';
export class NearestServiceHandler extends ServiceHandler {
protected buildServiceOptions(options: any, query: any): any {
if (query.number !== undefined) {
options.number = query.number;
}
return options;
}
protected async callOSRM(options: any): Promise<any> {
return this.osrm.nearest(options);
}
}
-33
View File
@@ -1,33 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OSRMWrapper = exports.version = void 0;
const util_1 = __importDefault(require("util"));
const OSRM = require('../lib/index.js');
exports.version = OSRM.version;
class OSRMWrapper {
constructor(osrmOptions) {
this.osrm = new OSRM(osrmOptions);
}
async tile(zxy) {
return util_1.default.promisify(this.osrm.tile.bind(this.osrm))(zxy);
}
async route(options) {
return util_1.default.promisify(this.osrm.route.bind(this.osrm))(options, { format: 'buffer' });
}
async nearest(options) {
return util_1.default.promisify(this.osrm.nearest.bind(this.osrm))(options, { format: 'buffer' });
}
async table(options) {
return util_1.default.promisify(this.osrm.table.bind(this.osrm))(options, { format: 'buffer' });
}
async trip(options) {
return util_1.default.promisify(this.osrm.trip.bind(this.osrm))(options, { format: 'buffer' });
}
async match(options) {
return util_1.default.promisify(this.osrm.match.bind(this.osrm))(options, { format: 'buffer' });
}
}
exports.OSRMWrapper = OSRMWrapper;
-36
View File
@@ -1,36 +0,0 @@
import util from 'util';
const OSRM = require('../lib/index.js');
export const version = OSRM.version;
export class OSRMWrapper {
private readonly osrm: typeof OSRM;
constructor(osrmOptions: any) {
this.osrm = new OSRM(osrmOptions);
}
async tile(zxy: [number, number, number]): Promise<any> {
return util.promisify(this.osrm.tile.bind(this.osrm))(zxy);
}
async route(options: any): Promise<any> {
return util.promisify(this.osrm.route.bind(this.osrm))(options, {format: 'buffer'});
}
async nearest(options: any): Promise<any> {
return util.promisify(this.osrm.nearest.bind(this.osrm))(options, {format: 'buffer'});
}
async table(options: any): Promise<any> {
return util.promisify(this.osrm.table.bind(this.osrm))(options, {format: 'buffer'});
}
async trip(options: any): Promise<any> {
return util.promisify(this.osrm.trip.bind(this.osrm))(options, {format: 'buffer'});
}
async match(options: any): Promise<any> {
return util.promisify(this.osrm.match.bind(this.osrm))(options, {format: 'buffer'});
}
}
-22
View File
@@ -1,22 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RouteServiceHandler = void 0;
const ServiceHandler_1 = require("./ServiceHandler");
class RouteServiceHandler extends ServiceHandler_1.ServiceHandler {
buildServiceOptions(options, query) {
if (query.alternatives) {
options.alternatives = query.alternatives;
}
if (query.approaches) {
options.approaches = query.approaches;
}
if (query.waypoints) {
options.waypoints = query.waypoints;
}
return options;
}
async callOSRM(options) {
return this.osrm.route(options);
}
}
exports.RouteServiceHandler = RouteServiceHandler;
-23
View File
@@ -1,23 +0,0 @@
import { ServiceHandler } from './ServiceHandler';
export class RouteServiceHandler extends ServiceHandler {
protected buildServiceOptions(options: any, query: any): any {
if (query.alternatives) {
options.alternatives = query.alternatives;
}
if (query.approaches) {
options.approaches = query.approaches;
}
if (query.waypoints) {
options.waypoints = query.waypoints;
}
return options;
}
protected async callOSRM(options: any): Promise<any> {
return this.osrm.route(options);
}
}
-74
View File
@@ -1,74 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceHandler = void 0;
class ServiceHandler {
constructor(osrm) {
this.osrm = osrm;
}
async handle(coordinates, query, format) {
const options = this.build(coordinates, query, format);
return this.callOSRM(options);
}
build(coordinates, query, format) {
const options = this.buildBaseOptions(coordinates, query, format);
return this.buildServiceOptions(options, query);
}
buildBaseOptions(coordinates, query, format) {
const options = {
coordinates: coordinates
};
this.handleCommonParams(query, options, format);
return options;
}
handleCommonParams(query, options, format) {
options.format = format;
if (query.overview) {
options.overview = query.overview;
}
if (query.geometries) {
options.geometries = query.geometries;
}
if (query.steps) {
options.steps = query.steps;
}
// TODO: annotations is per-service option
if (query.annotations) {
options.annotations = query.annotations;
}
if (query.exclude) {
options.exclude = query.exclude;
}
if (query.snapping) {
options.snapping = query.snapping;
}
if (query.radiuses) {
options.radiuses = query.radiuses.map((r) => {
if (r === 'unlimited') {
return null;
}
return r;
});
}
if (query.bearings) {
options.bearings = query.bearings.map((bearingWithRange) => {
if (bearingWithRange.length == 0) {
return null;
}
return bearingWithRange;
});
}
if (query.hints) {
options.hints = query.hints;
}
if (query.generate_hints) {
options.generate_hints = query.generate_hints;
}
if (query.skip_waypoints) {
options.skip_waypoints = query.skip_waypoints;
}
if (query.continue_straight) {
options.continue_straight = ['default', 'true'].includes(query.continue_straight);
}
}
}
exports.ServiceHandler = ServiceHandler;
-94
View File
@@ -1,94 +0,0 @@
import { Format } from './Format';
import { OSRMWrapper } from './OSRMWrapper';
export abstract class ServiceHandler {
public constructor(protected readonly osrm: OSRMWrapper) { }
public async handle(coordinates: [number, number][], query: any, format: Format): Promise<any> {
const options = this.build(coordinates, query, format);
return this.callOSRM(options);
}
private build(coordinates: [number, number][], query: any, format: Format): any {
const options = this.buildBaseOptions(coordinates, query, format);
return this.buildServiceOptions(options, query);
}
protected abstract buildServiceOptions(options: any, query: any): any;
protected abstract callOSRM(options: any): Promise<any>;
private buildBaseOptions(coordinates: [number, number][], query: any, format: Format): any {
const options: any = {
coordinates: coordinates
};
this.handleCommonParams(query, options, format);
return options;
}
private handleCommonParams(query: any, options: any, format: Format) {
options.format = format;
if (query.overview) {
options.overview = query.overview;
}
if (query.geometries) {
options.geometries = query.geometries;
}
if (query.steps) {
options.steps = query.steps;
}
// TODO: annotations is per-service option
if (query.annotations) {
options.annotations = query.annotations;
}
if (query.exclude) {
options.exclude = query.exclude;
}
if (query.snapping) {
options.snapping = query.snapping;
}
if (query.radiuses) {
options.radiuses = query.radiuses.map((r: string | 'unlimited') => {
if (r === 'unlimited') {
return null;
}
return r;
});
}
if (query.bearings) {
options.bearings = query.bearings.map((bearingWithRange: number[]) => {
if (bearingWithRange.length == 0) {
return null;
}
return bearingWithRange;
});
}
if (query.hints) {
options.hints = query.hints;
}
if (query.generate_hints) {
options.generate_hints = query.generate_hints;
}
if (query.skip_waypoints) {
options.skip_waypoints = query.skip_waypoints;
}
if (query.continue_straight) {
options.continue_straight = ['default', 'true'].includes(query.continue_straight);
}
}
}
-28
View File
@@ -1,28 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TableServiceHandler = void 0;
const ServiceHandler_1 = require("./ServiceHandler");
class TableServiceHandler extends ServiceHandler_1.ServiceHandler {
buildServiceOptions(options, query) {
if (query.scale_factor) {
options.scale_factor = query.scale_factor;
}
if (query.fallback_coordinate) {
options.fallback_coordinate = query.fallback_coordinate;
}
if (query.fallback_speed) {
options.fallback_speed = query.fallback_speed;
}
if (query.sources && query.sources !== 'all') {
options.sources = query.sources;
}
if (query.destinations && query.destinations !== 'all') {
options.destinations = query.destinations;
}
return options;
}
async callOSRM(options) {
return this.osrm.table(options);
}
}
exports.TableServiceHandler = TableServiceHandler;
-26
View File
@@ -1,26 +0,0 @@
import { ServiceHandler } from './ServiceHandler';
export class TableServiceHandler extends ServiceHandler {
protected buildServiceOptions(options: any, query: any): any {
if (query.scale_factor) {
options.scale_factor = query.scale_factor;
}
if (query.fallback_coordinate) {
options.fallback_coordinate = query.fallback_coordinate;
}
if (query.fallback_speed) {
options.fallback_speed = query.fallback_speed;
}
if (query.sources && query.sources !== 'all') {
options.sources = query.sources;
}
if (query.destinations && query.destinations !== 'all') {
options.destinations = query.destinations;
}
return options;
}
protected async callOSRM(options: any): Promise<any> {
return this.osrm.table(options);
}
}
-22
View File
@@ -1,22 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TripServiceHandler = void 0;
const ServiceHandler_1 = require("./ServiceHandler");
class TripServiceHandler extends ServiceHandler_1.ServiceHandler {
buildServiceOptions(options, query) {
if (query.roundtrip != null) {
options.roundtrip = query.roundtrip;
}
if (query.source) {
options.source = query.source;
}
if (query.destination) {
options.destination = query.destination;
}
return options;
}
async callOSRM(options) {
return this.osrm.trip(options);
}
}
exports.TripServiceHandler = TripServiceHandler;
-21
View File
@@ -1,21 +0,0 @@
import { ServiceHandler } from './ServiceHandler';
export class TripServiceHandler extends ServiceHandler {
protected buildServiceOptions(options: any, query: any): any {
if (query.roundtrip != null) {
options.roundtrip = query.roundtrip;
}
if (query.source) {
options.source = query.source;
}
if (query.destination) {
options.destination = query.destination;
}
return options;
}
protected async callOSRM(options: any): Promise<any> {
return this.osrm.trip(options);
}
}
-2810
View File
File diff suppressed because it is too large Load Diff
-44
View File
@@ -1,44 +0,0 @@
{
"name": "@project-osrm/osrm-routed",
"version": "5.28.0-unreleased",
"private": false,
"description": "API for OSRM",
"dependencies": {
"@fastify/compress": "^6.1.1",
"fastify": "^4.9.2",
"mkdirp": "^0.5.6",
"nan": "^2.17.0",
"node-cmake": "^2.5.1",
"rimraf": "^2.7.1"
},
"browserify": {
"transform": [
"babelify",
"brfs"
]
},
"bin": {
"osrm-routed-js": "./routed.js"
},
"repository": {
"type": "git",
"url": "https://github.com/Project-OSRM/osrm-backend.git"
},
"author": "Project OSRM Team",
"license": "BSD-2-Clause",
"bugs": {
"url": "https://github.com/Project-OSRM/osrm-backend/issues"
},
"homepage": "https://github.com/Project-OSRM/osrm-backend",
"engines": {
"node": ">=4.0.0"
},
"publishConfig": {
"access": "public"
},
"devDependencies": {
"@types/node": "^18.11.3",
"@types/yargs": "^17.0.13",
"typescript": "^4.8.4"
}
}
-168
View File
@@ -1,168 +0,0 @@
#!/usr/bin/env node
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fastify_1 = __importDefault(require("fastify"));
const OSRMWrapper_1 = require("./OSRMWrapper");
const yargs_1 = __importDefault(require("yargs/yargs"));
const cluster_1 = __importDefault(require("cluster"));
const os_1 = __importDefault(require("os"));
const schema_1 = require("./schema");
const MatchServiceHandler_1 = require("./MatchServiceHandler");
const NearestServiceHandler_1 = require("./NearestServiceHandler");
const RouteServiceHandler_1 = require("./RouteServiceHandler");
const TableServiceHandler_1 = require("./TableServiceHandler");
const TripServiceHandler_1 = require("./TripServiceHandler");
const Format_1 = require("./Format");
async function main() {
const argv = await (0, yargs_1.default)(process.argv.slice(2)).options({
ip: { type: 'string', default: '0.0.0.0', alias: 'i' },
port: { type: 'number', default: 5000, alias: 'p' },
workers: { type: 'number', alias: ['t', 'threads'], default: os_1.default.cpus().length },
shared_memory: { type: 'boolean', alias: ['shared-memory', 's'] },
mmap: { type: 'boolean', default: false, alias: ['m'] },
algorithm: { choices: ['CH', 'CoreCH', 'MLD'], default: 'CH', alias: 'a' },
dataset_name: { type: 'string', alias: 'dataset-name' },
max_viaroute_size: { type: 'number', alias: 'max-viaroute-size', default: 500 },
max_trip_size: { type: 'number', alias: 'max-trip-size', default: 100 },
max_table_size: { type: 'number', alias: 'max-table-size', default: 100 },
max_matching_size: { type: 'number', alias: 'max-matching-size', default: 100 },
max_nearest_size: { type: 'number', alias: 'max-nearest-size', default: 100 },
max_alternatives: { type: 'number', alias: 'max-alternatives', default: 3 },
max_matching_radius: { type: 'number', alias: 'max-matching-radius', default: -1 },
version: { alias: 'v' }
})
.help('h')
.alias('h', 'help')
.strict()
.argv;
if (argv.version) {
process.stdout.write(`v${OSRMWrapper_1.version}\n`);
return;
}
if (argv._.length == 0 && !argv.shared_memory) {
// TODO: show usage
return;
}
const osrm = new OSRMWrapper_1.OSRMWrapper({
path: argv._[0],
dataset_name: argv.dataset_name,
algorithm: argv.algorithm,
shared_memory: argv.shared_memory,
mmap_memory: argv.mmap,
max_viaroute_size: argv.max_viaroute_size,
max_trip_size: argv.max_trip_size,
max_table_size: argv.max_table_size,
max_matching_size: argv.max_matching_size,
max_nearest_size: argv.max_nearest_size,
max_alternatives: argv.max_alternatives,
max_matching_radius: argv.max_matching_size
});
const fastify = (0, fastify_1.default)({
logger: true,
maxParamLength: Number.MAX_SAFE_INTEGER,
rewriteUrl: (req) => {
// https://github.com/fastify/fastify/issues/2487
return req.url.replace(/;/g, '%3B');
},
querystringParser: schema_1.parseQueryString
});
await fastify.register(Promise.resolve().then(() => __importStar(require('@fastify/compress'))));
async function processRequest(handler, request, reply) {
const { coordinatesAndFormat } = request.params;
const query = request.query;
try {
const { format, coordinates } = (0, schema_1.parseCoordinatesAndFormat)(coordinatesAndFormat);
switch (format) {
case Format_1.Format.Json:
reply.type('application/json').code(200);
break;
case Format_1.Format.Flatbuffers:
reply.type('application/x-flatbuffers;schema=osrm.engine.api.fbresult').code(200);
break;
}
return handler.handle(coordinates, query, format);
}
catch (e) {
reply.code(400);
// TODO: bindings do not return `message`, but put `code` into `message`
return {
code: e.message,
message: e.message
};
}
}
fastify.get('/route/v1/:profile/:coordinatesAndFormat', { schema: schema_1.routeSchema }, async (request, reply) => {
return processRequest(new RouteServiceHandler_1.RouteServiceHandler(osrm), request, reply);
});
fastify.get('/nearest/v1/:profile/:coordinatesAndFormat', { schema: schema_1.nearestSchema }, async (request, reply) => {
return processRequest(new NearestServiceHandler_1.NearestServiceHandler(osrm), request, reply);
});
fastify.get('/table/v1/:profile/:coordinatesAndFormat', { schema: schema_1.tableSchema }, async (request, reply) => {
return processRequest(new TableServiceHandler_1.TableServiceHandler(osrm), request, reply);
});
fastify.get('/match/v1/:profile/:coordinatesAndFormat', { schema: schema_1.matchSchema }, async (request, reply) => {
return processRequest(new MatchServiceHandler_1.MatchServiceHandler(osrm), request, reply);
});
fastify.get('/trip/v1/:profile/:coordinatesAndFormat', { schema: schema_1.tripSchema }, async (request, reply) => {
return processRequest(new TripServiceHandler_1.TripServiceHandler(osrm), request, reply);
});
fastify.get('/tile/v1/:profile/tile(:x,:y,:zoom).mvt', { schema: schema_1.tileSchema }, async (request, reply) => {
const { x, y, zoom } = request.params;
reply.type('application/x-protobuf').code(200);
return osrm.tile([zoom, x, y]);
});
const start = async () => {
try {
await fastify.listen({ port: argv.port, host: argv.ip });
process.stdout.write('running and waiting for requests\n');
}
catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
const clusterWorkerSize = argv.workers;
if (clusterWorkerSize > 1) {
if (cluster_1.default.isMaster) {
for (let i = 0; i < clusterWorkerSize; i++) {
cluster_1.default.fork();
}
cluster_1.default.on("exit", function (worker) {
console.log("Worker", worker.id, " has exited.");
});
}
else {
start();
}
}
else {
start();
}
}
main();
-165
View File
@@ -1,165 +0,0 @@
#!/usr/bin/env node
import Fastify, { FastifyReply, FastifyRequest } from 'fastify';
import { OSRMWrapper, version as OSRMVersion } from './OSRMWrapper';
import yargs from 'yargs/yargs';
import cluster from 'cluster';
import os from 'os';
import { routeSchema, nearestSchema, tableSchema, tripSchema, matchSchema, tileSchema, parseQueryString, parseCoordinatesAndFormat } from './schema';
import { ServiceHandler } from './ServiceHandler';
import { MatchServiceHandler } from './MatchServiceHandler';
import { NearestServiceHandler } from './NearestServiceHandler';
import { RouteServiceHandler } from './RouteServiceHandler';
import { TableServiceHandler } from './TableServiceHandler';
import { TripServiceHandler } from './TripServiceHandler';
import { Format } from './Format';
async function main() {
const argv = await yargs(process.argv.slice(2)).options({
ip: { type: 'string', default: '0.0.0.0', alias: 'i' },
port: { type: 'number', default: 5000, alias: 'p' },
workers: { type: 'number', alias: ['t', 'threads'], default: os.cpus().length },
shared_memory: { type: 'boolean', alias: ['shared-memory', 's'] },
mmap: { type: 'boolean', default: false, alias: ['m'] },
algorithm: { choices: ['CH', 'CoreCH', 'MLD'], default: 'CH', alias: 'a' },
dataset_name: { type: 'string', alias: 'dataset-name' },
max_viaroute_size: { type: 'number', alias: 'max-viaroute-size', default: 500 },
max_trip_size: { type: 'number', alias: 'max-trip-size', default: 100 },
max_table_size: { type: 'number', alias: 'max-table-size', default: 100 },
max_matching_size: { type: 'number', alias: 'max-matching-size', default: 100 },
max_nearest_size: { type: 'number', alias: 'max-nearest-size', default: 100 },
max_alternatives: { type: 'number', alias: 'max-alternatives', default: 3 },
max_matching_radius: { type: 'number', alias: 'max-matching-radius', default: -1 },
version: { alias: 'v' }
})
.help('h')
.alias('h', 'help')
.strict()
.argv;
if (argv.version) {
process.stdout.write(`v${OSRMVersion}\n`);
return;
}
if (argv._.length == 0 && !argv.shared_memory) {
// TODO: show usage
return;
}
const osrm = new OSRMWrapper({
path: argv._[0],
dataset_name: argv.dataset_name,
algorithm: argv.algorithm,
shared_memory: argv.shared_memory,
mmap_memory: argv.mmap,
max_viaroute_size: argv.max_viaroute_size,
max_trip_size: argv.max_trip_size,
max_table_size: argv.max_table_size,
max_matching_size: argv.max_matching_size,
max_nearest_size: argv.max_nearest_size,
max_alternatives: argv.max_alternatives,
max_matching_radius: argv.max_matching_size
});
const fastify = Fastify({
logger: true,
maxParamLength: Number.MAX_SAFE_INTEGER,
rewriteUrl: (req) => {
// https://github.com/fastify/fastify/issues/2487
return req.url!.replace(/;/g, '%3B');
},
querystringParser: parseQueryString
});
await fastify.register(
import('@fastify/compress')
);
async function processRequest(handler: ServiceHandler, request: FastifyRequest, reply: FastifyReply) {
const { coordinatesAndFormat } = request.params as any;
const query = request.query as any;
try {
const { format, coordinates } = parseCoordinatesAndFormat(coordinatesAndFormat);
switch (format) {
case Format.Json:
reply.type('application/json').code(200);
break;
case Format.Flatbuffers:
reply.type('application/x-flatbuffers;schema=osrm.engine.api.fbresult').code(200);
break;
}
return handler.handle(coordinates, query, format);
} catch (e: any) {
reply.code(400);
// TODO: bindings do not return `message`, but put `code` into `message`
return {
code: e.message,
message: e.message
};
}
}
fastify.get('/route/v1/:profile/:coordinatesAndFormat', { schema: routeSchema }, async (request, reply) => {
return processRequest(new RouteServiceHandler(osrm), request, reply);
});
fastify.get('/nearest/v1/:profile/:coordinatesAndFormat', { schema: nearestSchema }, async (request, reply) => {
return processRequest(new NearestServiceHandler(osrm), request, reply);
});
fastify.get('/table/v1/:profile/:coordinatesAndFormat', { schema: tableSchema }, async (request, reply) => {
return processRequest(new TableServiceHandler(osrm), request, reply);
});
fastify.get('/match/v1/:profile/:coordinatesAndFormat', { schema: matchSchema }, async (request, reply) => {
return processRequest(new MatchServiceHandler(osrm), request, reply);
});
fastify.get('/trip/v1/:profile/:coordinatesAndFormat', { schema: tripSchema }, async (request, reply) => {
return processRequest(new TripServiceHandler(osrm), request, reply);
});
fastify.get('/tile/v1/:profile/tile(:x,:y,:zoom).mvt', { schema: tileSchema }, async (request, reply) => {
const { x, y, zoom } = request.params as any;
reply.type('application/x-protobuf').code(200);
return osrm.tile([zoom, x, y]);
});
const start = async () => {
try {
await fastify.listen({ port: argv.port, host: argv.ip });
process.stdout.write('running and waiting for requests\n');
} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
const clusterWorkerSize = argv.workers;
if (clusterWorkerSize > 1) {
if (cluster.isMaster) {
for (let i=0; i < clusterWorkerSize; i++) {
cluster.fork();
}
cluster.on("exit", function(worker: any) {
console.log("Worker", worker.id, " has exited.")
})
} else {
start();
}
} else {
start();
}
}
main();
-337
View File
@@ -1,337 +0,0 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseCoordinatesAndFormat = exports.parseQueryString = exports.tileSchema = exports.tripSchema = exports.matchSchema = exports.tableSchema = exports.nearestSchema = exports.routeSchema = void 0;
const querystring_1 = __importDefault(require("querystring"));
const Format_1 = require("./Format");
const ajv_1 = __importDefault(require("ajv"));
function makeAnnotationsSchema(allowedAnnotations) {
return {
oneOf: [
{
type: 'array',
items: {
enum: allowedAnnotations
}
},
{
type: 'boolean'
}
],
default: false
};
}
const queryStringJsonSchemaGeneral = {
type: 'object',
properties: {
// TODO: check numbers of elements is the same in bearings and radiuses
bearings: {
type: 'array',
items: {
type: 'array',
// TODO: check [min;max]
items: {
type: 'number'
}
}
},
radiuses: {
type: 'array',
items: {
anyOf: [
{
type: 'number',
exclusiveMinimum: 0
},
{
type: 'string',
enum: ['unlimited']
}
]
}
},
generate_hints: { type: 'boolean', default: true },
hints: {
type: 'array',
items: {
type: 'string'
}
},
approaches: {
type: 'array',
items: {
// TODO: default?
enum: ['curb', 'unrestricted']
}
},
exclude: {
type: 'array',
items: {
type: 'string'
}
},
snapping: {
enum: ['any', 'default'],
default: 'default'
},
skip_waypoints: { type: 'boolean', default: false },
}
};
const queryStringJsonSchemaRoute = {
type: 'object',
properties: {
...queryStringJsonSchemaGeneral.properties,
// TODO: strict mode: use allowUnionTypes to allow union
alternatives: { type: ['boolean', 'integer'], default: false },
steps: { type: 'boolean', default: false },
annotations: makeAnnotationsSchema(['duration', 'nodes', 'distance', 'weight', 'datasources', 'speed']),
geometries: {
enum: ['polyline', 'polyline6', 'geojson'],
default: 'polyline'
},
overview: {
enum: ['simplified', 'full', 'false'],
default: 'simplified'
},
continue_straight: {
enum: ['default', 'true', 'false'],
default: 'default'
},
waypoints: {
type: 'array',
items: {
type: 'integer'
}
}
}
};
const queryStringJsonSchemaNearest = {
type: 'object',
properties: {
...queryStringJsonSchemaGeneral.properties,
number: { type: ['integer'], default: 1 }
}
};
const queryStringJsonSchemaTable = {
type: 'object',
properties: {
...queryStringJsonSchemaGeneral.properties,
sources: {
anyOf: [
{
type: 'array',
items: {
type: 'integer',
minimum: 0
}
},
{
type: 'string',
enum: ['all']
}
]
},
destinations: {
anyOf: [
{
type: 'array',
items: {
type: 'integer',
minimum: 0
}
},
{
type: 'string',
enum: ['all']
}
]
},
annotations: {
type: 'array',
items: {
enum: ['duration', 'distance'],
default: 'duration'
}
},
fallback_speed: {
type: 'number',
exclusiveMinimum: 0
},
fallback_coordinate: {
enum: ['input', 'snapped'],
default: 'input'
},
scale_factor: {
type: 'number',
exclusiveMinimum: 0
}
}
};
const queryStringJsonSchemaMatch = {
type: 'object',
properties: {
...queryStringJsonSchemaGeneral.properties,
steps: { type: 'boolean', default: false },
geometries: {
enum: ['polyline', 'polyline6', 'geojson'],
default: 'polyline'
},
overview: {
enum: ['simplified', 'full', 'false'],
default: 'simplified'
},
timestamps: {
type: 'array',
items: {
type: 'integer'
}
},
gaps: {
enum: ['split', 'ignore'],
default: 'split'
},
tidy: { type: 'boolean', default: false },
waypoints: {
type: 'array',
items: {
type: 'integer'
}
},
annotations: makeAnnotationsSchema(['duration', 'nodes', 'distance', 'weight', 'datasources', 'speed'])
}
};
const queryStringJsonSchemaTrip = {
type: 'object',
properties: {
...queryStringJsonSchemaGeneral.properties,
roundtrip: { type: 'boolean', default: true },
source: {
enum: ['any', 'first'],
default: 'any'
},
destination: {
enum: ['any', 'last'],
default: 'any'
},
annotations: makeAnnotationsSchema(['duration', 'nodes', 'distance', 'weight', 'datasources', 'speed']),
steps: { type: 'boolean', default: false },
geometries: {
enum: ['polyline', 'polyline6', 'geojson'],
default: 'polyline'
},
overview: {
enum: ['simplified', 'full', 'false'],
default: 'simplified'
}
}
};
const paramsJsonSchema = {
type: 'object',
properties: {
coordinatesAndFormat: {
type: 'string'
}
}
};
exports.routeSchema = {
querystring: queryStringJsonSchemaRoute,
params: paramsJsonSchema
};
exports.nearestSchema = {
querystring: queryStringJsonSchemaNearest,
params: paramsJsonSchema
};
exports.tableSchema = {
querystring: queryStringJsonSchemaTable,
params: paramsJsonSchema
};
exports.matchSchema = {
querystring: queryStringJsonSchemaMatch,
params: paramsJsonSchema
};
exports.tripSchema = {
querystring: queryStringJsonSchemaTrip,
params: paramsJsonSchema
};
const paramsJsonSchemaTile = {
type: 'object',
properties: {
z: { type: 'integer', minimum: 12, maximum: 22 },
x: { type: 'integer', minimum: 0 },
y: { type: 'integer', minimum: 0 },
},
};
exports.tileSchema = {
params: paramsJsonSchemaTile,
};
function parseArray(listString, separator) {
// `querystring` parses `foo=1&foo=2` as `{ foo: ['1', '2'] }`
if (Array.isArray(listString)) {
return listString;
}
return listString.split(separator);
}
function parseQueryString(queryString) {
const parsed = querystring_1.default.parse(queryString, '&', '=', {
// 0 means "infinity"
maxKeys: 0
});
for (const key of ['timestamps', 'radiuses', 'approaches', 'waypoints', 'hints']) {
if (key in parsed) {
parsed[key] = parseArray(parsed[key], ';');
}
}
for (const key of ['sources', 'destinations']) {
if (key in parsed && parsed[key] !== 'all') {
parsed[key] = parseArray(parsed[key], ';');
}
}
if ('exclude' in parsed) {
parsed['exclude'] = parseArray(parsed['exclude'], ',');
}
if ('bearings' in parsed) {
parsed['bearings'] = parseArray(parsed['bearings'], ';').map(bearingWithRange => parseArray(bearingWithRange, ',').filter(bearing => bearing !== ''));
}
if ('annotations' in parsed) {
if (!['true', 'false'].includes(parsed['annotations'])) {
parsed['annotations'] = parseArray(parsed['annotations'], ',');
}
}
return parsed;
}
exports.parseQueryString = parseQueryString;
const coordinatesSchema = new ajv_1.default({ allErrors: true, coerceTypes: true }).compile({
type: 'array',
items: {
type: 'array',
items: {
type: 'number',
// TODO: ranges
minimum: -180,
maximum: 180
},
minItems: 2,
maxItems: 2
},
minItems: 1
});
function parseCoordinatesAndFormat(coordinatesAndFormat) {
let format = Format_1.Format.Json;
// try to handle case when we have format(i.e. `.flatbuffers` or `.json`) at the end
const lastDotIndex = coordinatesAndFormat.lastIndexOf('.');
if (lastDotIndex > 0) {
const formatString = coordinatesAndFormat.slice(lastDotIndex);
if (formatString == '.flatbuffers' || formatString == '.json') {
coordinatesAndFormat = coordinatesAndFormat.slice(0, lastDotIndex);
format = formatString == '.flatbuffers' ? Format_1.Format.Flatbuffers : Format_1.Format.Json;
}
}
const coordinates = coordinatesAndFormat.split(';').map(c => c.split(','));
if (!coordinatesSchema(coordinates)) {
throw { message: 'Invalid coordinates', code: 'InvalidQuery' };
}
return { coordinates: coordinates, format };
}
exports.parseCoordinatesAndFormat = parseCoordinatesAndFormat;
-360
View File
@@ -1,360 +0,0 @@
import querystring from 'querystring';
import { Format } from './Format';
import Ajv from 'ajv';
function makeAnnotationsSchema(allowedAnnotations: string[]): any {
return {
oneOf: [
{
type: 'array',
items: {
enum: allowedAnnotations
}
},
{
type: 'boolean'
}
],
default: false
};
}
const queryStringJsonSchemaGeneral = {
type: 'object',
properties: {
// TODO: check numbers of elements is the same in bearings and radiuses
bearings: {
type: 'array',
items: {
type: 'array',
// TODO: check [min;max]
items: {
type: 'number'
}
}
},
radiuses: {
type: 'array',
items: {
anyOf: [
{
type: 'number',
exclusiveMinimum: 0
},
{
type: 'string',
enum: ['unlimited']
}
]
}
},
generate_hints: { type: 'boolean', default: true },
hints: {
type: 'array',
items: {
type: 'string'
}
},
approaches: {
type: 'array',
items: {
// TODO: default?
enum: ['curb', 'unrestricted']
}
},
exclude: {
type: 'array',
items: {
type: 'string'
}
},
snapping: {
enum: ['any', 'default'],
default: 'default'
},
skip_waypoints: { type: 'boolean', default: false },
}
};
const queryStringJsonSchemaRoute = {
type: 'object',
properties: {
...queryStringJsonSchemaGeneral.properties,
// TODO: strict mode: use allowUnionTypes to allow union
alternatives: { type: ['boolean', 'integer'], default: false },
steps: { type: 'boolean', default: false },
annotations: makeAnnotationsSchema(['duration', 'nodes', 'distance', 'weight', 'datasources', 'speed']),
geometries: {
enum: ['polyline', 'polyline6', 'geojson'],
default: 'polyline'
},
overview: {
enum: ['simplified', 'full', 'false'],
default: 'simplified'
},
continue_straight: {
enum: ['default', 'true', 'false'],
default: 'default'
},
waypoints: {
type: 'array',
items: {
type: 'integer'
}
}
}
};
const queryStringJsonSchemaNearest = {
type: 'object',
properties: {
...queryStringJsonSchemaGeneral.properties,
number: { type: ['integer'], default: 1 }
}
};
const queryStringJsonSchemaTable = {
type: 'object',
properties: {
...queryStringJsonSchemaGeneral.properties,
sources: {
anyOf: [
{
type: 'array',
items: {
type: 'integer',
minimum: 0
}
},
{
type: 'string',
enum: ['all']
}
]
},
destinations: {
anyOf: [
{
type: 'array',
items: {
type: 'integer',
minimum: 0
}
},
{
type: 'string',
enum: ['all']
}
]
},
annotations: {
type: 'array',
items: {
enum: ['duration', 'distance'],
default: 'duration'
}
},
fallback_speed: {
type: 'number',
exclusiveMinimum: 0
},
fallback_coordinate: {
enum: ['input', 'snapped'],
default: 'input'
},
scale_factor: {
type: 'number',
exclusiveMinimum: 0
}
}
};
const queryStringJsonSchemaMatch = {
type: 'object',
properties: {
...queryStringJsonSchemaGeneral.properties,
steps: { type: 'boolean', default: false },
geometries: {
enum: ['polyline', 'polyline6', 'geojson'],
default: 'polyline'
},
overview: {
enum: ['simplified', 'full', 'false'],
default: 'simplified'
},
timestamps: {
type: 'array',
items: {
type: 'integer'
}
},
gaps: {
enum: ['split', 'ignore'],
default: 'split'
},
tidy: { type: 'boolean', default: false },
waypoints: {
type: 'array',
items: {
type: 'integer'
}
},
annotations: makeAnnotationsSchema(['duration', 'nodes', 'distance', 'weight', 'datasources', 'speed'])
}
};
const queryStringJsonSchemaTrip = {
type: 'object',
properties: {
...queryStringJsonSchemaGeneral.properties,
roundtrip: { type: 'boolean', default: true },
source: {
enum: ['any', 'first'],
default: 'any'
},
destination: {
enum: ['any', 'last'],
default: 'any'
},
annotations: makeAnnotationsSchema(['duration', 'nodes', 'distance', 'weight', 'datasources', 'speed']),
steps: { type: 'boolean', default: false },
geometries: {
enum: ['polyline', 'polyline6', 'geojson'],
default: 'polyline'
},
overview: {
enum: ['simplified', 'full', 'false'],
default: 'simplified'
}
}
};
const paramsJsonSchema = {
type: 'object',
properties: {
coordinatesAndFormat: {
type: 'string'
}
}
};
export const routeSchema = {
querystring: queryStringJsonSchemaRoute,
params: paramsJsonSchema
};
export const nearestSchema = {
querystring: queryStringJsonSchemaNearest,
params: paramsJsonSchema
};
export const tableSchema = {
querystring: queryStringJsonSchemaTable,
params: paramsJsonSchema
};
export const matchSchema = {
querystring: queryStringJsonSchemaMatch,
params: paramsJsonSchema
};
export const tripSchema = {
querystring: queryStringJsonSchemaTrip,
params: paramsJsonSchema
};
const paramsJsonSchemaTile = {
type: 'object',
properties: {
z: { type: 'integer', minimum: 12, maximum: 22 },
x: { type: 'integer', minimum: 0 },
y: { type: 'integer', minimum: 0 },
},
};
export const tileSchema = {
params: paramsJsonSchemaTile,
};
function parseArray(listString: string | string[], separator: string): string[] {
// `querystring` parses `foo=1&foo=2` as `{ foo: ['1', '2'] }`
if (Array.isArray(listString)) {
return listString;
}
return listString.split(separator);
}
export function parseQueryString(queryString: string): any {
const parsed: any = querystring.parse(queryString, '&', '=', {
// 0 means "infinity"
maxKeys: 0
});
for (const key of ['timestamps', 'radiuses', 'approaches', 'waypoints', 'hints']) {
if (key in parsed) {
parsed[key] = parseArray(parsed[key], ';');
}
}
for (const key of ['sources', 'destinations']) {
if (key in parsed && parsed[key] !== 'all') {
parsed[key] = parseArray(parsed[key], ';');
}
}
if ('exclude' in parsed) {
parsed['exclude'] = parseArray(parsed['exclude'], ',');
}
if ('bearings' in parsed) {
parsed['bearings'] = parseArray(parsed['bearings'], ';').map(bearingWithRange => parseArray(bearingWithRange, ',').filter(bearing => bearing !== ''));
}
if ('annotations' in parsed) {
if (!['true', 'false'].includes(parsed['annotations'])) {
parsed['annotations'] = parseArray(parsed['annotations'], ',');
}
}
return parsed;
}
const coordinatesSchema = new Ajv({ allErrors: true, coerceTypes: true }).compile({
type: 'array',
items: {
type: 'array',
items: {
type: 'number',
// TODO: ranges
minimum: -180,
maximum: 180
},
minItems: 2,
maxItems: 2
},
minItems: 1
});
export function parseCoordinatesAndFormat(coordinatesAndFormat: string): { coordinates: [number, number][], format: Format } {
let format: Format = Format.Json;
// try to handle case when we have format(i.e. `.flatbuffers` or `.json`) at the end
const lastDotIndex = coordinatesAndFormat.lastIndexOf('.');
if (lastDotIndex > 0) {
const formatString = coordinatesAndFormat.slice(lastDotIndex);
if (formatString == '.flatbuffers' || formatString == '.json') {
coordinatesAndFormat = coordinatesAndFormat.slice(0, lastDotIndex);
format = formatString == '.flatbuffers' ? Format.Flatbuffers : Format.Json;
}
}
const coordinates: any = coordinatesAndFormat.split(';').map(c => c.split(','));
if (!coordinatesSchema(coordinates)) {
throw {message: 'Invalid coordinates', code: 'InvalidQuery'};
}
return { coordinates: coordinates as [number, number][], format };
}
-14
View File
@@ -1,14 +0,0 @@
{
"compilerOptions": {
"lib": ["es2020"],
"target": "es2020",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
"include": [
"./*"
]
}
-14
View File
@@ -16,17 +16,3 @@ do
{ set +x; } 2>/dev/null { set +x; } 2>/dev/null
done done
done done
# we do not run `osrm-routed-js` tests on v12 since fastify doesn't support it
NODE_VERSION=$(node --version)
NODE_MAJOR_VERSION=$(echo $NODE_VERSION | cut -d. -f1)
if [[ "$NODE_MAJOR_VERSION" != "v12" ]]; then
echo "Running osrm-routed-js tests"
export OSRM_USE_ROUTED_JS=1
node ./node_modules/cucumber/bin/cucumber.js features/ -p verify_routed_js
node ./node_modules/cucumber/bin/cucumber.js features/ -p mld_routed_js
unset OSRM_USE_ROUTED_JS
else
echo "Skipping osrm-routed-js tests on Node.js ${NODE_VERSION}"
fi
-21
View File
@@ -1,21 +0,0 @@
#!/bin/sh
set -e
# we do not run `osrm-routed-js` tests on v12 since fastify doesn't support it
NODE_VERSION=$(node --version)
NODE_MAJOR_VERSION=$(echo $NODE_VERSION | cut -d. -f1)
if [[ "$NODE_MAJOR_VERSION" != "v12" ]]; then
echo "Running osrm-routed-js tests"
export OSRM_USE_ROUTED_JS=1
node ./node_modules/cucumber/bin/cucumber.js features/ -p verify_routed_js
node ./node_modules/cucumber/bin/cucumber.js features/ -p mld_routed_js
unset OSRM_USE_ROUTED_JS
else
echo "Skipping osrm-routed-js tests on Node.js ${NODE_VERSION}"
fi
node ./node_modules/cucumber/bin/cucumber.js features/ -p verify
node ./node_modules/cucumber/bin/cucumber.js features/ -p verify -m mmap
node ./node_modules/cucumber/bin/cucumber.js features/ -p mld
node ./node_modules/cucumber/bin/cucumber.js features/ -p mld -m mmap
+2 -2
View File
@@ -508,7 +508,7 @@ void encodeVectorTile(const DataFacadeBase &facade,
auto tile_line = coordinatesToTileLine(a, b, tile_bbox); auto tile_line = coordinatesToTileLine(a, b, tile_bbox);
if (!tile_line.empty()) if (!tile_line.empty())
{ {
SpeedLayerFeatureBuilder fbuilder{speeds_layer, id}; SpeedLayerFeatureBuilder fbuilder{speeds_layer, id++};
fbuilder.add_linestring_from_container(tile_line); fbuilder.add_linestring_from_container(tile_line);
fbuilder.set_speed(speed_kmh_idx); fbuilder.set_speed(speed_kmh_idx);
@@ -542,7 +542,7 @@ void encodeVectorTile(const DataFacadeBase &facade,
auto tile_line = coordinatesToTileLine(b, a, tile_bbox); auto tile_line = coordinatesToTileLine(b, a, tile_bbox);
if (!tile_line.empty()) if (!tile_line.empty())
{ {
SpeedLayerFeatureBuilder fbuilder{speeds_layer, id}; SpeedLayerFeatureBuilder fbuilder{speeds_layer, id++};
fbuilder.add_linestring_from_container(tile_line); fbuilder.add_linestring_from_container(tile_line);
fbuilder.set_speed(speed_kmh_idx); fbuilder.set_speed(speed_kmh_idx);
+17 -16
View File
@@ -608,26 +608,12 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
BOOST_ASSERT(!edge_data1.reversed); BOOST_ASSERT(!edge_data1.reversed);
BOOST_ASSERT(!edge_data2.reversed); BOOST_ASSERT(!edge_data2.reversed);
// We write out the mapping between the edge-expanded edges and the original nodes.
// Since each edge represents a possible maneuver, external programs can use this to
// quickly perform updates to edge weights in order to penalize certain turns.
// If this edge is 'trivial' -- where the compressed edge corresponds exactly to an
// original OSM segment -- we can pull the turn's preceding node ID directly with
// `node_along_road_entering`;
// otherwise, we need to look up the node immediately preceding the turn from the
// compressed edge container.
const bool isTrivial = m_compressed_edge_container.IsTrivial(node_based_edge_from);
const auto &from_node =
isTrivial ? node_along_road_entering
: m_compressed_edge_container.GetLastEdgeSourceID(node_based_edge_from);
// compute weight and duration penalties // compute weight and duration penalties
// In theory we shouldn't get a directed traffic light on a turn, as it indicates that // In theory we shouldn't get a directed traffic light on a turn, as it indicates that
// the traffic signal direction was potentially ambiguously annotated on the junction // the traffic signal direction was potentially ambiguously annotated on the junction
// node But we'll check anyway. // node But we'll check anyway.
const auto is_traffic_light = m_traffic_signals.HasSignal(from_node, intersection_node); const auto is_traffic_light =
m_traffic_signals.HasSignal(node_along_road_entering, intersection_node);
const auto is_uturn = const auto is_uturn =
guidance::getTurnDirection(turn_angle) == guidance::DirectionModifier::UTurn; guidance::getTurnDirection(turn_angle) == guidance::DirectionModifier::UTurn;
@@ -694,6 +680,21 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
true, true,
false}; false};
// We write out the mapping between the edge-expanded edges and the original nodes.
// Since each edge represents a possible maneuver, external programs can use this to
// quickly perform updates to edge weights in order to penalize certain turns.
// If this edge is 'trivial' -- where the compressed edge corresponds exactly to an
// original OSM segment -- we can pull the turn's preceding node ID directly with
// `node_along_road_entering`;
// otherwise, we need to look up the node immediately preceding the turn from the
// compressed edge container.
const bool isTrivial = m_compressed_edge_container.IsTrivial(node_based_edge_from);
const auto &from_node =
isTrivial ? node_along_road_entering
: m_compressed_edge_container.GetLastEdgeSourceID(node_based_edge_from);
const auto &to_node = const auto &to_node =
m_compressed_edge_container.GetFirstEdgeTargetID(node_based_edge_to); m_compressed_edge_container.GetFirstEdgeTargetID(node_based_edge_to);
+6 -1
View File
@@ -706,7 +706,12 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
const auto accurate_distance = const auto accurate_distance =
util::coordinate_calculation::greatCircleDistance(source_coord, target_coord); util::coordinate_calculation::greatCircleDistance(source_coord, target_coord);
ExtractionSegment segment(source_coord, target_coord, distance, weight, duration); ExtractionSegment segment(source_coord,
target_coord,
distance,
weight,
duration,
edge_iterator->result.flags);
scripting_environment.ProcessSegment(segment); scripting_environment.ProcessSegment(segment);
auto &edge = edge_iterator->result; auto &edge = edge_iterator->result;
+4 -1
View File
@@ -20,7 +20,7 @@ namespace osrm::extractor
static constexpr int SECOND_TO_DECISECOND = 10; static constexpr int SECOND_TO_DECISECOND = 10;
void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes, void GraphCompressor::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,
@@ -338,6 +338,9 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
// update any involved turn relations // update any involved turn relations
turn_path_compressor.Compress(node_u, node_v, node_w); turn_path_compressor.Compress(node_u, node_v, node_w);
// Update traffic signal paths containing compressed node.
traffic_signals.Compress(node_u, node_v, node_w);
// Forward and reversed compressed edge lengths need to match. // Forward and reversed compressed edge lengths need to match.
// Set a dummy empty penalty weight if opposite value exists. // Set a dummy empty penalty weight if opposite value exists.
auto set_dummy_penalty = [](EdgeWeight &weight_penalty, auto set_dummy_penalty = [](EdgeWeight &weight_penalty,
@@ -887,19 +887,21 @@ CoordinateExtractor::PrepareLengthCache(const std::vector<util::Coordinate> &coo
segment_distances.push_back(0); segment_distances.push_back(0);
// sentinel // sentinel
// NOLINTNEXTLINE(bugprone-unused-return-value) // NOLINTNEXTLINE(bugprone-unused-return-value)
std::find_if(std::next(std::begin(coordinates)), // We're only interested in the side effect of the lambda, not the return value
std::end(coordinates), [[maybe_unused]] auto _ = std::find_if(
[last_coordinate = coordinates.front(), std::next(std::begin(coordinates)),
limit, std::end(coordinates),
&segment_distances, [last_coordinate = coordinates.front(),
accumulated_distance = 0.](const util::Coordinate current_coordinate) mutable { limit,
const auto distance = util::coordinate_calculation::greatCircleDistance( &segment_distances,
last_coordinate, current_coordinate); accumulated_distance = 0.](const util::Coordinate current_coordinate) mutable {
accumulated_distance += distance; const auto distance = util::coordinate_calculation::greatCircleDistance(
last_coordinate = current_coordinate; last_coordinate, current_coordinate);
segment_distances.push_back(distance); accumulated_distance += distance;
return accumulated_distance >= limit; last_coordinate = current_coordinate;
}); segment_distances.push_back(distance);
return accumulated_distance >= limit;
});
return segment_distances; return segment_distances;
} }
@@ -1090,7 +1092,8 @@ CoordinateExtractor::SampleCoordinates(const std::vector<util::Coordinate> &coor
}; };
// misuse of adjacent_find. Loop over coordinates, until a total sample length is reached // misuse of adjacent_find. Loop over coordinates, until a total sample length is reached
std::adjacent_find(coordinates.begin(), coordinates.end(), add_samples_until_length_limit); [[maybe_unused]] auto _ =
std::adjacent_find(coordinates.begin(), coordinates.end(), add_samples_until_length_limit);
return sampled_coordinates; return sampled_coordinates;
} }
+2 -2
View File
@@ -17,7 +17,7 @@ NodeBasedGraphFactory::NodeBasedGraphFactory(
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,
const TrafficSignals &traffic_signals, TrafficSignals &traffic_signals,
std::unordered_set<NodeID> &&barriers, std::unordered_set<NodeID> &&barriers,
std::vector<util::Coordinate> &&coordinates, std::vector<util::Coordinate> &&coordinates,
extractor::PackedOSMIDs &&osm_node_ids, extractor::PackedOSMIDs &&osm_node_ids,
@@ -72,7 +72,7 @@ void NodeBasedGraphFactory::BuildCompressedOutputGraph(const std::vector<NodeBas
void NodeBasedGraphFactory::Compress(ScriptingEnvironment &scripting_environment, void NodeBasedGraphFactory::Compress(ScriptingEnvironment &scripting_environment,
std::vector<TurnRestriction> &turn_restrictions, std::vector<TurnRestriction> &turn_restrictions,
std::vector<UnresolvedManeuverOverride> &maneuver_overrides, std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
const TrafficSignals &traffic_signals) TrafficSignals &traffic_signals)
{ {
GraphCompressor graph_compressor; GraphCompressor graph_compressor;
graph_compressor.Compress(barriers, graph_compressor.Compress(barriers,
+33 -1
View File
@@ -471,6 +471,36 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
[](ExtractionRelationContainer &cont, const ExtractionRelation::OsmIDTyped &rel_id) [](ExtractionRelationContainer &cont, const ExtractionRelation::OsmIDTyped &rel_id)
-> const ExtractionRelation & { return cont.GetRelationData(rel_id); }); -> const ExtractionRelation & { return cont.GetRelationData(rel_id); });
context.state.new_usertype<NodeBasedEdgeClassification>(
"NodeBasedEdgeClassification",
"forward",
// can't just do &NodeBasedEdgeClassification::forward with bitfields
sol::property([](NodeBasedEdgeClassification &c) -> bool { return c.forward; }),
"backward",
sol::property([](NodeBasedEdgeClassification &c) -> bool { return c.backward; }),
"is_split",
sol::property([](NodeBasedEdgeClassification &c) -> bool { return c.is_split; }),
"roundabout",
sol::property([](NodeBasedEdgeClassification &c) -> bool { return c.roundabout; }),
"circular",
sol::property([](NodeBasedEdgeClassification &c) -> bool { return c.circular; }),
"startpoint",
sol::property([](NodeBasedEdgeClassification &c) -> bool { return c.startpoint; }),
"restricted",
sol::property([](NodeBasedEdgeClassification &c) -> bool { return c.restricted; }),
"road_classification",
sol::property([](NodeBasedEdgeClassification &c) -> RoadClassification {
return c.road_classification;
}),
"highway_turn_classification",
sol::property([](NodeBasedEdgeClassification &c) -> uint8_t {
return c.highway_turn_classification;
}),
"access_turn_classification",
sol::property([](NodeBasedEdgeClassification &c) -> uint8_t {
return c.access_turn_classification;
}));
context.state.new_usertype<ExtractionSegment>("ExtractionSegment", context.state.new_usertype<ExtractionSegment>("ExtractionSegment",
"source", "source",
&ExtractionSegment::source, &ExtractionSegment::source,
@@ -481,7 +511,9 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
"weight", "weight",
&ExtractionSegment::weight, &ExtractionSegment::weight,
"duration", "duration",
&ExtractionSegment::duration); &ExtractionSegment::duration,
"flags",
&ExtractionSegment::flags);
// Keep in mind .location is available only if .pbf is preprocessed to set the location with the // Keep in mind .location is available only if .pbf is preprocessed to set the location with the
// ref using osmium command "osmium add-locations-to-ways" // ref using osmium command "osmium add-locations-to-ways"
+4 -4
View File
@@ -292,7 +292,7 @@ inline void asyncForTiles(const Napi::CallbackInfo &info,
* @param {String} [options.geometries=polyline] Returned route geometry format (influences overview and per step). Can also be `geojson`. * @param {String} [options.geometries=polyline] Returned route geometry format (influences overview and per step). Can also be `geojson`.
* @param {String} [options.overview=simplified] Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). * @param {String} [options.overview=simplified] Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`).
* @param {Boolean} [options.continue_straight] 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. * @param {Boolean} [options.continue_straight] 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.
* @param {Array} [options.approaches] Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`. * @param {Array} [options.approaches] 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`
* @param {Array} [options.waypoints] Indices to coordinates to treat as waypoints. If not supplied, all coordinates are waypoints. Must include first and last coordinate index. * @param {Array} [options.waypoints] Indices to coordinates to treat as waypoints. If not supplied, all coordinates are waypoints. Must include first and last coordinate index.
* @param {String} [options.format] Which output format to use, either `json`, or [`flatbuffers`](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api/flatbuffers). * @param {String} [options.format] Which output format to use, either `json`, or [`flatbuffers`](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api/flatbuffers).
@@ -337,7 +337,7 @@ Napi::Value Engine::route(const Napi::CallbackInfo &info)
* @param {Boolean} [options.generate_hints=true] Whether or not adds a Hint to the response which can be used in subsequent requests. * @param {Boolean} [options.generate_hints=true] Whether or not adds a Hint to the response which can be used in subsequent requests.
* @param {Number} [options.number=1] Number of nearest segments that should be returned. * @param {Number} [options.number=1] Number of nearest segments that should be returned.
* Must be an integer greater than or equal to `1`. * Must be an integer greater than or equal to `1`.
* @param {Array} [options.approaches] Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`. * @param {Array} [options.approaches] Restrict the direction on the road network at a waypoint, relative to the input coordinate. Can be `null` (unrestricted, default), `curb` or `opposite`.
* @param {String} [options.format] Which output format to use, either `json`, or [`flatbuffers`](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api/flatbuffers). * @param {String} [options.format] Which output format to use, either `json`, or [`flatbuffers`](https://github.com/Project-OSRM/osrm-backend/tree/master/include/engine/api/flatbuffers).
* @param {String} [options.snapping] 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. * @param {String} [options.snapping] 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.
* @param {Function} callback * @param {Function} callback
@@ -384,7 +384,7 @@ Napi::Value Engine::nearest(const Napi::CallbackInfo &info)
* @param {Array} [options.sources] An array of `index` elements (`0 <= integer < #coordinates`) to use * @param {Array} [options.sources] 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.
* @param {Array} [options.destinations] An array of `index` elements (`0 <= integer < #coordinates`) to use location with given index as destination. Default is to use all. * @param {Array} [options.destinations] An array of `index` elements (`0 <= integer < #coordinates`) to use location with given index as destination. Default is to use all.
* @param {Array} [options.approaches] Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`. * @param {Array} [options.approaches] Restrict the direction on the road network at a waypoint, relative to the input coordinate.. Can be `null` (unrestricted, default), `curb` or `opposite`.
* @param {Number} [options.fallback_speed] Replace `null` responses in result with as-the-crow-flies estimates based on `fallback_speed`. Value is in metres/second. * @param {Number} [options.fallback_speed] Replace `null` responses in result with as-the-crow-flies estimates based on `fallback_speed`. Value is in metres/second.
* @param {String} [options.fallback_coordinate] 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. * @param {String} [options.fallback_coordinate] 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.
* @param {Number} [options.scale_factor] Multiply the table duration values in the table by this number for more controlled input into a route optimization solver. * @param {Number} [options.scale_factor] Multiply the table duration values in the table by this number for more controlled input into a route optimization solver.
@@ -565,7 +565,7 @@ Napi::Value Engine::match(const Napi::CallbackInfo &info)
* @param {Boolean} [options.roundtrip=true] Return route is a roundtrip. * @param {Boolean} [options.roundtrip=true] Return route is a roundtrip.
* @param {String} [options.source=any] Return route starts at `any` or `first` coordinate. * @param {String} [options.source=any] Return route starts at `any` or `first` coordinate.
* @param {String} [options.destination=any] Return route ends at `any` or `last` coordinate. * @param {String} [options.destination=any] Return route ends at `any` or `last` coordinate.
* @param {Array} [options.approaches] Keep waypoints on curb side. Can be `null` (unrestricted, default) or `curb`. * @param {Array} [options.approaches] Restrict the direction on the road network at a waypoint, relative to the input coordinate. Can be `null` (unrestricted, default), `curb` or `opposite`.
* @param {String} [options.snapping] 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. * @param {String} [options.snapping] 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.
* *
* @returns {Object} containing `waypoints` and `trips`. * @returns {Object} containing `waypoints` and `trips`.
+3 -1
View File
@@ -195,7 +195,9 @@ std::size_t DinicMaxFlow::BlockingFlow(FlowEdges &flow,
}; };
// augment all adjacent edges // augment all adjacent edges
std::adjacent_find(path.begin(), path.end(), augment_one); // We're only interested in the side-effect of the augment_one function, the return
// value is ignored
[[maybe_unused]] auto _ = std::adjacent_find(path.begin(), path.end(), augment_one);
}; };
const auto augment_all_paths = [&](const NodeID sink_node_id) { const auto augment_all_paths = [&](const NodeID sink_node_id) {
+8
View File
@@ -162,6 +162,14 @@ int Partitioner::Run(const PartitionerConfig &config)
extractor::files::readManeuverOverrides(filename, maneuver_overrides, node_sequences); extractor::files::readManeuverOverrides(filename, maneuver_overrides, node_sequences);
renumber(maneuver_overrides, permutation); renumber(maneuver_overrides, permutation);
renumber(node_sequences, permutation); renumber(node_sequences, permutation);
// Although the vector is already sorted, the rename function changes the identifiers, so
// the order is not sorted now. So we sort by `from_node` again, so that later lookups can
// be done with a binary search.
std::sort(maneuver_overrides.begin(),
maneuver_overrides.end(),
[](const auto &a, const auto &b) { return a.start_node < b.start_node; });
extractor::files::writeManeuverOverrides(filename, maneuver_overrides, node_sequences); extractor::files::writeManeuverOverrides(filename, maneuver_overrides, node_sequences);
} }
if (boost::filesystem::exists(config.GetPath(".osrm.hsgr"))) if (boost::filesystem::exists(config.GetPath(".osrm.hsgr")))
+8 -3
View File
@@ -7,14 +7,17 @@
#include <boost/iostreams/filter/gzip.hpp> #include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filtering_stream.hpp> #include <boost/iostreams/filtering_stream.hpp>
#include <fmt/format.h>
#include <vector> #include <vector>
namespace osrm::server namespace osrm::server
{ {
Connection::Connection(boost::asio::io_context &io_context, RequestHandler &handler) Connection::Connection(boost::asio::io_context &io_context,
RequestHandler &handler,
short keepalive_timeout)
: strand(boost::asio::make_strand(io_context)), TCP_socket(strand), timer(strand), : strand(boost::asio::make_strand(io_context)), TCP_socket(strand), timer(strand),
request_handler(handler) request_handler(handler), keepalive_timeout(keepalive_timeout)
{ {
} }
@@ -88,7 +91,9 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
{ {
keep_alive = true; keep_alive = true;
current_reply.headers.emplace_back("Connection", "keep-alive"); current_reply.headers.emplace_back("Connection", "keep-alive");
current_reply.headers.emplace_back("Keep-Alive", "timeout=5, max=512"); current_reply.headers.emplace_back("Keep-Alive",
"timeout=" + fmt::to_string(keepalive_timeout) +
", max=" + fmt::to_string(processed_requests));
} }
// compress the result w/ gzip/deflate if requested // compress the result w/ gzip/deflate if requested
+18 -4
View File
@@ -107,7 +107,8 @@ inline unsigned generateServerProgramOptions(const int argc,
int &ip_port, int &ip_port,
bool &trial, bool &trial,
EngineConfig &config, EngineConfig &config,
int &requested_thread_num) int &requested_thread_num,
short &keepalive_timeout)
{ {
using boost::filesystem::path; using boost::filesystem::path;
using boost::program_options::value; using boost::program_options::value;
@@ -140,6 +141,9 @@ inline unsigned generateServerProgramOptions(const int argc,
("threads,t", ("threads,t",
value<int>(&requested_thread_num)->default_value(hardware_threads), value<int>(&requested_thread_num)->default_value(hardware_threads),
"Number of threads to use") // "Number of threads to use") //
("keepalive-timeout,k",
value<short>(&keepalive_timeout)->default_value(5),
"Default keepalive-timeout. Default: 5 seconds.") //
("shared-memory,s", ("shared-memory,s",
value<bool>(&config.use_shared_memory)->implicit_value(true)->default_value(false), value<bool>(&config.use_shared_memory)->implicit_value(true)->default_value(false),
"Load data from shared memory") // "Load data from shared memory") //
@@ -266,8 +270,16 @@ try
boost::filesystem::path base_path; boost::filesystem::path base_path;
int requested_thread_num = 1; int requested_thread_num = 1;
const unsigned init_result = generateServerProgramOptions( short keepalive_timeout = 5;
argc, argv, base_path, ip_address, ip_port, trial_run, config, requested_thread_num); const unsigned init_result = generateServerProgramOptions(argc,
argv,
base_path,
ip_address,
ip_port,
trial_run,
config,
requested_thread_num,
keepalive_timeout);
if (init_result == INIT_OK_DO_NOT_START_ENGINE) if (init_result == INIT_OK_DO_NOT_START_ENGINE)
{ {
return EXIT_SUCCESS; return EXIT_SUCCESS;
@@ -307,6 +319,7 @@ try
util::Log() << "Threads: " << requested_thread_num; util::Log() << "Threads: " << requested_thread_num;
util::Log() << "IP address: " << ip_address; util::Log() << "IP address: " << ip_address;
util::Log() << "IP port: " << ip_port; util::Log() << "IP port: " << ip_port;
util::Log() << "Keepalive timeout: " << keepalive_timeout;
#ifndef _WIN32 #ifndef _WIN32
int sig = 0; int sig = 0;
@@ -319,7 +332,8 @@ try
#endif #endif
auto service_handler = std::make_unique<server::ServiceHandler>(config); auto service_handler = std::make_unique<server::ServiceHandler>(config);
auto routing_server = server::Server::CreateServer(ip_address, ip_port, requested_thread_num); auto routing_server =
server::Server::CreateServer(ip_address, ip_port, requested_thread_num, keepalive_timeout);
routing_server->RegisterServiceHandler(std::move(service_handler)); routing_server->RegisterServiceHandler(std::move(service_handler));
+2 -1
View File
@@ -323,7 +323,8 @@ double findClosestDistance(const std::vector<Coordinate> &lhs, const std::vector
return false; return false;
}; };
// NOLINTNEXTLINE(bugprone-unused-return-value) // NOLINTNEXTLINE(bugprone-unused-return-value)
std::find_if(std::begin(lhs), std::end(lhs), compute_minimum_distance_in_rhs); [[maybe_unused]] auto _ =
std::find_if(std::begin(lhs), std::end(lhs), compute_minimum_distance_in_rhs);
return current_min; return current_min;
} }
+4
View File
@@ -150,6 +150,7 @@
{"key": "maxspeed", "value": "AT:trunk"}, {"key": "maxspeed", "value": "AT:trunk"},
{"key": "maxspeed", "value": "BE:motorway"}, {"key": "maxspeed", "value": "BE:motorway"},
{"key": "maxspeed", "value": "BE-VLG:rural"}, {"key": "maxspeed", "value": "BE-VLG:rural"},
{"key": "maxspeed", "value": "BG:motorway"},
{"key": "maxspeed", "value": "BY:urban"}, {"key": "maxspeed", "value": "BY:urban"},
{"key": "maxspeed", "value": "BY:motorway"}, {"key": "maxspeed", "value": "BY:motorway"},
{"key": "maxspeed", "value": "CA-ON:rural"}, {"key": "maxspeed", "value": "CA-ON:rural"},
@@ -171,6 +172,9 @@
{"key": "maxspeed", "value": "NL:trunk"}, {"key": "maxspeed", "value": "NL:trunk"},
{"key": "maxspeed", "value": "NO:rural"}, {"key": "maxspeed", "value": "NO:rural"},
{"key": "maxspeed", "value": "NO:motorway"}, {"key": "maxspeed", "value": "NO:motorway"},
{"key": "maxspeed", "value": "PH:urban"},
{"key": "maxspeed", "value": "PH:rural"},
{"key": "maxspeed", "value": "PH:motorway"},
{"key": "maxspeed", "value": "PL:rural"}, {"key": "maxspeed", "value": "PL:rural"},
{"key": "maxspeed", "value": "PL:trunk"}, {"key": "maxspeed", "value": "PL:trunk"},
{"key": "maxspeed", "value": "PL:motorway"}, {"key": "maxspeed", "value": "PL:motorway"},
+1 -1
View File
@@ -10,7 +10,7 @@ exports.three_test_coordinates = [[7.41337, 43.72956],
exports.two_test_coordinates = exports.three_test_coordinates.slice(0, 2) exports.two_test_coordinates = exports.three_test_coordinates.slice(0, 2)
exports.test_tile = {'at': [17059, 11948, 15], 'size': 156539}; exports.test_tile = {'at': [17059, 11948, 15], 'size': 159125};
// Test files generated by the routing engine; check test/data // Test files generated by the routing engine; check test/data
if (process.env.OSRM_DATA_PATH !== undefined) { if (process.env.OSRM_DATA_PATH !== undefined) {
+7 -3
View File
@@ -573,7 +573,7 @@ test('route: throws on bad radiuses', function(assert) {
}); });
test('route: routes Monaco with valid approaches values', function(assert) { test('route: routes Monaco with valid approaches values', function(assert) {
assert.plan(3); assert.plan(4);
var osrm = new OSRM(monaco_path); var osrm = new OSRM(monaco_path);
var options = { var options = {
coordinates: two_test_coordinates, coordinates: two_test_coordinates,
@@ -586,6 +586,10 @@ test('route: routes Monaco with valid approaches values', function(assert) {
osrm.route(options, function(err, route) { osrm.route(options, function(err, route) {
assert.ifError(err); assert.ifError(err);
}); });
options.approaches = ['opposite', 'opposite'];
osrm.route(options, function(err, route) {
assert.ifError(err);
});
options.approaches = ['unrestricted', null]; options.approaches = ['unrestricted', null];
osrm.route(options, function(err, route) { osrm.route(options, function(err, route) {
assert.ifError(err); assert.ifError(err);
@@ -609,12 +613,12 @@ test('route: throws on bad approaches', function(assert) {
coordinates: two_test_coordinates, coordinates: two_test_coordinates,
approaches: ['curb', 'test'] approaches: ['curb', 'test']
}, function(err, route) {}) }, }, function(err, route) {}) },
/'approaches' param must be one of \[curb, unrestricted\]/); /'approaches' param must be one of \[curb, opposite, unrestricted\]/);
assert.throws(function() { osrm.route({ assert.throws(function() { osrm.route({
coordinates: two_test_coordinates, coordinates: two_test_coordinates,
approaches: [10, 15] approaches: [10, 15]
}, function(err, route) {}) }, }, function(err, route) {}) },
/Approach must be a string: \[curb, unrestricted\] or null/); /Approach must be a string: \[curb, opposite, unrestricted\] or null/);
}); });
test('route: routes Monaco with custom limits on MLD', function(assert) { test('route: routes Monaco with custom limits on MLD', function(assert) {
+2 -2
View File
@@ -451,7 +451,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
boost::none, boost::none,
engine::Approach::CURB, engine::Approach::CURB,
engine::Approach::UNRESTRICTED, engine::Approach::UNRESTRICTED,
engine::Approach::CURB, engine::Approach::OPPOSITE,
}; };
RouteParameters reference_18{false, RouteParameters reference_18{false,
false, false,
@@ -466,7 +466,7 @@ BOOST_AUTO_TEST_CASE(valid_route_urls)
approaches_18}; approaches_18};
auto result_18 = parseParameters<RouteParameters>( auto result_18 = parseParameters<RouteParameters>(
"1,2;3,4;5,6;7,8?steps=false&approaches=;curb;unrestricted;curb"); "1,2;3,4;5,6;7,8?steps=false&approaches=;curb;unrestricted;opposite");
BOOST_CHECK(result_18); BOOST_CHECK(result_18);
BOOST_CHECK_EQUAL(reference_18.steps, result_18->steps); BOOST_CHECK_EQUAL(reference_18.steps, result_18->steps);
BOOST_CHECK_EQUAL(reference_18.alternatives, result_18->alternatives); BOOST_CHECK_EQUAL(reference_18.alternatives, result_18->alternatives);