Compare commits

...

19 Commits

Author SHA1 Message Date
Siarhei Fedartsou d3cd40ea9e Try to add Conan debug builds 2024-05-13 15:52:21 +02:00
Siarhei Fedartsou ee8e0f890a Optimise path distance calculation in MLD map matching (#6876) 2024-05-11 16:30:43 +02:00
Dennis Luxen 1e2ffee97c Update Makefile: fix typo (#6878) 2024-05-11 09:13:17 +02:00
Michael Bell ffc39b8ad2 Clarify use of forcing routing steps (#6866)
The change clarifies the conditions for forcing routing steps and
simplifies the codebase to support it.

- Makes explicity  the search runtime condition for forcing a routing
step. Namely, the node is a source of the forward and reverse searches,
and it's one of the pre-identified nodes that requires a step to
be forced.
- Consolidate the two lists of force nodes into one. Not only is there
no algorithmic value in separating the nodes by geometric direction,
the  improvements to via-routes with u-turns mean atleast one of these
lists will be empty for any search.
- Rename 'force loop' to 'force step'. This moves the code away
from the original CH-specific language for checking for self-loops
in the case where this condition is met. MLD does not have loops.

Additional cucumber tests are added to cover the logic related to
negative search weights and forcing routing steps on via-route
paths.
2024-05-10 22:00:24 +01:00
Dennis Luxen 70969186f6 Migrate GCC CI jobs to run on GCC 11, 12, and 13 (#6865) 2024-05-10 20:38:32 +02:00
Dennis Luxen dff76d31d5 Remove dead code branches (#6875) 2024-05-10 20:21:41 +02:00
Siarhei Fedartsou 3254686933 Use M1 runner to build arm64 macOS builds (#6868) 2024-05-08 21:08:11 +02:00
Siarhei Fedartsou a6dfff725b Configure GitHub Actions concurrency (#6870) 2024-05-08 10:06:04 +02:00
Dennis Luxen 10237b8761 Update vendored vtzero dependency to v1.1.0 (#6871) 2024-05-07 22:19:48 +02:00
Dennis Luxen 79de092bb2 Upgrade fmt dependency to v10.2.1 (#6869)
* Put fmt into version agnostic subdir

* Add fmt to dependency update script

* Remove manually added fmt

* Squashed 'third_party/fmt/' content from commit e69e5f977

git-subtree-dir: third_party/fmt
git-subtree-split: e69e5f977d458f2650bb346dadf2ad30c5320281
2024-05-07 20:55:55 +02:00
Dennis Luxen 82aa369db3 Remove dead code modernization script (#6863) 2024-05-06 19:09:10 +02:00
Dennis Luxen 0583582772 Remove include that breaks compilation for Boost v1.85.0 (#6856)
* Remove include that breaks compilation for Boost v1.85.0

* Update CHANGELOG.md

* Fix typo

* Fix issues found by newer clang-tidy version

* Add include to boost filesystem to satisfy Windows compiler
2024-05-06 18:52:40 +02:00
Dennis Luxen 99809e105c Upgrade clang compiler in CI builds (#6861) 2024-05-06 18:12:17 +02:00
Dennis Luxen 6d361ced41 Set Windows build to quiet (#6862)
The normal flag generates 290 megabytes of log output for a regular build. Setting it to quiet will reduce this and still print errors.
2024-05-06 17:31:58 +02:00
Dennis Luxen 790fa901c7 Remove stale AppVeyor files (#6860)
* Drop left-overs from deprecated AppVeyor CI build

* Update CHANGELOG.md
2024-05-06 13:48:24 +02:00
Dennis Luxen 7f9d591ab7 Upgrade clang-format to version 15 (#6859) 2024-05-06 09:14:46 +02:00
Michael Bell b503e96a98 Remove force-loop checks for routes with u-turns (#6858)
Each leg of a via-route supporting u-turns does not need to consider
force-loops. Negative weight checks are sufficient to prevent
incorrect results when waypoints are on the same edge.
2024-05-05 21:56:01 +01:00
Dennis Luxen d691af4860 Remove outdated/deprecated CMake policy (#6854) 2024-05-05 22:08:40 +02:00
Dennis Luxen befd9dc5ae Merge pull request #6857 from DennisOSRM/upgrade_js_dependencies
Drop support for NodeJS <= v16
2024-05-05 20:29:16 +02:00
475 changed files with 33911 additions and 50463 deletions
+117 -139
View File
@@ -19,6 +19,10 @@ env:
CMAKE_VERSION: 3.21.2
ENABLE_NODE_BINDINGS: "ON"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
windows-release-node:
needs: format-taginfo-docs
@@ -26,7 +30,6 @@ jobs:
continue-on-error: false
env:
BUILD_TYPE: Release
ENABLE_APPLE_SILICON: "OFF"
steps:
- uses: actions/checkout@v3
- run: pip install "conan<2.0.0"
@@ -71,7 +74,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
format-taginfo-docs:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Use Node.js
@@ -88,7 +91,7 @@ jobs:
- name: Prepare environment
run: |
npm ci --ignore-scripts
clang-format-10 --version
clang-format-15 --version
- name: Run checks
run: |
./scripts/check_taginfo.py taginfo.json profiles/car.lua
@@ -145,42 +148,52 @@ jobs:
strategy:
matrix:
include:
- name: gcc-9-debug-cov
- name: gcc-13-debug-cov
continue-on-error: false
node: 18
runs-on: ubuntu-20.04
node: 20
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Debug
CCOMPILER: gcc-9
CCOMPILER: gcc-13
CUCUMBER_TIMEOUT: 20000
CXXCOMPILER: g++-9
CXXCOMPILER: g++-13
ENABLE_COVERAGE: ON
- name: gcc-9-debug-asan-ubsan
- name: clang-15-debug-asan-ubsan
continue-on-error: false
node: 18
runs-on: ubuntu-20.04
node: 20
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Debug
CCOMPILER: gcc-9
CCOMPILER: clang-15
CUCUMBER_TIMEOUT: 20000
CXXCOMPILER: g++-9
CXXCOMPILER: clang++-15
ENABLE_SANITIZER: ON
TARGET_ARCH: x86_64-asan-ubsan
OSRM_CONNECTION_RETRIES: 10
OSRM_CONNECTION_EXP_BACKOFF_COEF: 1.5
- name: clang-6.0-debug
- name: clang-15-release
continue-on-error: false
node: 18
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Debug
CCOMPILER: clang-6.0
CXXCOMPILER: clang++-6.0
BUILD_TYPE: Release
CCOMPILER: clang-15
CXXCOMPILER: clang++-15
CUCUMBER_TIMEOUT: 60000
- name: clang-15.0-debug-clang-tidy
- name: clang-15-debug
continue-on-error: false
node: 18
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Debug
CCOMPILER: clang-15
CXXCOMPILER: clang++-15
CUCUMBER_TIMEOUT: 60000
- name: clang-15-debug-clang-tidy
continue-on-error: false
node: 18
runs-on: ubuntu-22.04
@@ -191,30 +204,71 @@ jobs:
CUCUMBER_TIMEOUT: 60000
ENABLE_CLANG_TIDY: ON
- name: clang-14-release
continue-on-error: false
node: 18
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: clang-14
CXXCOMPILER: clang++-14
CUCUMBER_TIMEOUT: 60000
- name: clang-13-release
continue-on-error: false
node: 18
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: clang-13
CXXCOMPILER: clang++-13
CUCUMBER_TIMEOUT: 60000
- name: conan-linux-debug-asan-ubsan
continue-on-error: false
node: 18
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: clang-11
CXXCOMPILER: clang++-11
BUILD_TYPE: Debug
CCOMPILER: clang-15
CXXCOMPILER: clang++-15
ENABLE_CONAN: ON
ENABLE_SANITIZER: ON
- name: conan-linux-release
continue-on-error: false
node: 18
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: clang-6.0
CXXCOMPILER: clang++-6.0
CCOMPILER: clang-15
CXXCOMPILER: clang++-15
ENABLE_CONAN: ON
- name: conan-linux-debug
continue-on-error: false
node: 18
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Debug
CCOMPILER: clang-15
CXXCOMPILER: clang++-15
ENABLE_CONAN: ON
- name: gcc-13-release
continue-on-error: false
node: 20
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: gcc-13
CXXCOMPILER: g++-13
ENABLE_BENCHMARKS: ON
CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized'
- name: gcc-12-release
continue-on-error: false
node: 18
node: 20
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
@@ -225,64 +279,22 @@ jobs:
- name: gcc-11-release
continue-on-error: false
node: 18
runs-on: ubuntu-20.04
node: 20
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: gcc-11
CXXCOMPILER: g++-11
ENABLE_BENCHMARKS: ON
- name: gcc-10-release
continue-on-error: false
node: 18
runs-on: ubuntu-20.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: gcc-10
CXXCOMPILER: g++-10
- name: gcc-9-release
continue-on-error: false
node: 18
runs-on: ubuntu-20.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: gcc-9
CXXCOMPILER: g++-9
CXXFLAGS: -Wno-cast-function-type
- name: gcc-9-conan-release-i686
continue-on-error: false
node: 18
runs-on: ubuntu-20.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: gcc-9
CFLAGS: "-m32 -msse2 -mfpmath=sse"
CXXCOMPILER: g++-9
CXXFLAGS: "-m32 -msse2 -mfpmath=sse"
TARGET_ARCH: i686
ENABLE_CONAN: ON
- name: gcc-8-release
continue-on-error: false
node: 18
runs-on: ubuntu-20.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: gcc-8
CXXCOMPILER: g++-8
CXXFLAGS: -Wno-cast-function-type
- name: conan-linux-release-node
build_node_package: true
continue-on-error: false
node: 20
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
BUILD_TYPE: Release
CCOMPILER: clang-6.0
CXXCOMPILER: clang++-6.0
CCOMPILER: clang-13
CXXCOMPILER: clang++-13
ENABLE_CONAN: ON
NODE_PACKAGE_TESTS_ONLY: ON
@@ -290,10 +302,10 @@ jobs:
build_node_package: true
continue-on-error: false
node: 20
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
BUILD_TYPE: Debug
CCOMPILER: clang-6.0
CXXCOMPILER: clang++-6.0
CCOMPILER: clang-13
CXXCOMPILER: clang++-13
ENABLE_CONAN: ON
NODE_PACKAGE_TESTS_ONLY: ON
@@ -301,7 +313,7 @@ jobs:
build_node_package: true
continue-on-error: true
node: 20
runs-on: macos-11
runs-on: macos-13 # x86_64
BUILD_TYPE: Release
CCOMPILER: clang
CXXCOMPILER: clang++
@@ -313,14 +325,13 @@ jobs:
build_node_package: true
continue-on-error: true
node: 20
runs-on: macos-11
runs-on: macos-14 # arm64
BUILD_TYPE: Release
CCOMPILER: clang
CXXCOMPILER: clang++
CUCUMBER_TIMEOUT: 60000
ENABLE_ASSERTIONS: ON
ENABLE_CONAN: ON
ENABLE_APPLE_SILICON: ON
name: ${{ matrix.name}}
continue-on-error: ${{ matrix.continue-on-error }}
@@ -340,13 +351,13 @@ jobs:
ENABLE_CONAN: ${{ matrix.ENABLE_CONAN }}
ENABLE_SANITIZER: ${{ matrix.ENABLE_SANITIZER }}
NODE_PACKAGE_TESTS_ONLY: ${{ matrix.NODE_PACKAGE_TESTS_ONLY }}
ENABLE_APPLE_SILICON: ${{ matrix.ENABLE_APPLE_SILICON }}
TARGET_ARCH: ${{ matrix.TARGET_ARCH }}
OSRM_CONNECTION_RETRIES: ${{ matrix.OSRM_CONNECTION_RETRIES }}
OSRM_CONNECTION_EXP_BACKOFF_COEF: ${{ matrix.OSRM_CONNECTION_EXP_BACKOFF_COEF }}
steps:
- uses: actions/checkout@v3
- name: Build machine architecture
run: uname -m
- name: Use Node.js
uses: actions/setup-node@v3
with:
@@ -369,9 +380,9 @@ jobs:
uses: actions/cache@v3
with:
path: ~/.conan
key: v7-conan-${{ matrix.name }}-${{ github.sha }}
key: v9-conan-${{ matrix.name }}-${{ github.sha }}
restore-keys: |
v7-conan-${{ matrix.name }}-
v9-conan-${{ matrix.name }}-
- name: Enable test cache
uses: actions/cache@v3
with:
@@ -390,6 +401,7 @@ jobs:
# We can only set this after checkout once we know the workspace directory
echo "LSAN_OPTIONS=print_suppressions=0:suppressions=${GITHUB_WORKSPACE}/scripts/ci/leaksanitizer.conf" >> $GITHUB_ENV
echo "UBSAN_OPTIONS=symbolize=1:halt_on_error=1:print_stacktrace=1:suppressions=${GITHUB_WORKSPACE}/scripts/ci/undefinedsanitizer.conf" >> $GITHUB_ENV
echo "ASAN_OPTIONS=print_suppressions=0:suppressions=${GITHUB_WORKSPACE}/scripts/ci/addresssanitizer.conf" >> $GITHUB_ENV
fi
if [[ "${RUNNER_OS}" == "Linux" ]]; then
@@ -400,7 +412,7 @@ jobs:
- name: Install dev dependencies
run: |
python3 -m pip install "conan<2.0.0"
python3 -m pip install "conan<2.0.0" || python3 -m pip install "conan<2.0.0" --break-system-packages
# workaround for issue that GitHub Actions seems to not adding it to PATH after https://github.com/actions/runner-images/pull/6499
# and that's why CI cannot find conan executable installed above
@@ -415,19 +427,8 @@ jobs:
brew install ccache
fi
# clang
if [[ "${CCOMPILER}" == "clang-6.0" ]]; then
sudo apt-get update -y && sudo apt-get install clang++-6
elif [[ "${CCOMPILER}" == "clang-15" ]]; then
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-get update -y && sudo apt-get install software-properties-common
sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main'
sudo apt-get update -y && sudo apt-get install clang++-15 clang-tidy-15
sudo update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-15 100000
fi
# Linux dev packages
if [ "${TARGET_ARCH}" != "i686" ] && [ "${ENABLE_CONAN}" != "ON" ]; then
if [ "${ENABLE_CONAN}" != "ON" ]; then
sudo apt-get update -y
sudo apt-get install -y libbz2-dev libxml2-dev libzip-dev liblua5.2-dev libboost-all-dev
if [[ "${CCOMPILER}" != clang-* ]]; then
@@ -436,9 +437,6 @@ jobs:
if [[ "${ENABLE_COVERAGE}" == "ON" ]]; then
sudo apt-get install -y lcov
fi
elif [[ $TARGET_ARCH == "i686" ]]; then
source ./scripts/ci/before_install.${TARGET_ARCH}.sh
echo "PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig:${PKG_CONFIG_PATH}" >> $GITHUB_ENV
fi
# TBB
@@ -474,16 +472,6 @@ jobs:
echo "Using ${JOBS} jobs"
pushd ${OSRM_BUILD_DIR}
# handle Apple Silicon cross compilation
if [[ "${ENABLE_APPLE_SILICON}" == "ON" ]]; then
ARCH=arm64
TARGET="${ARCH}-apple-darwin"
CFLAGS="$CFLAGS --target=$TARGET"
CXXFLAGS="$CXXFLAGS --target=$TARGET"
APPLE_SILICON_FLAGS=(-DCMAKE_C_COMPILER_TARGET="$TARGET" -DCMAKE_CXX_COMPILER_TARGET="$TARGET" -DCMAKE_SYSTEM_PROCESSOR="${ARCH}" -DCMAKE_SYSTEM_NAME="Darwin" -DCMAKE_C_FLAGS="$CFLAGS" -DCMAKE_CXX_FLAGS="$CXXFLAGS")
else
APPLE_SILICON_FLAGS=()
fi
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_CONAN=${ENABLE_CONAN:-OFF} \
@@ -495,12 +483,10 @@ jobs:
-DENABLE_SANITIZER=${ENABLE_SANITIZER:-OFF} \
-DBUILD_TOOLS=${BUILD_TOOLS:-OFF} \
-DENABLE_CCACHE=ON \
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
"${APPLE_SILICON_FLAGS[@]}"
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR}
make --jobs=${JOBS}
if [[ "${NODE_PACKAGE_TESTS_ONLY}" != "ON" && "${ENABLE_APPLE_SILICON}" != "ON" ]]; then
if [[ "${NODE_PACKAGE_TESTS_ONLY}" != "ON" ]]; then
make tests --jobs=${JOBS}
make benchmarks --jobs=${JOBS}
ccache -s
@@ -512,14 +498,14 @@ jobs:
fi
popd
- name: Build example
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY != 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY != 'ON' }}
run: |
mkdir example/build && pushd example/build
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
make --jobs=${JOBS}
popd
- name: Run all tests
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY != 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY != 'ON' }}
run: |
make -C test/data benchmark
@@ -530,7 +516,7 @@ jobs:
# All tests assume to be run from the build directory
pushd ${OSRM_BUILD_DIR}
for i in ./unit_tests/*-tests ; do echo Running $i ; $i ; done
if [ -z "${ENABLE_SANITIZER}" ] && [ "$TARGET_ARCH" != "i686" ]; then
if [ -z "${ENABLE_SANITIZER}" ]; then
npm run nodejs-tests
fi
popd
@@ -542,38 +528,39 @@ jobs:
make --jobs=${JOBS} benchmarks
./src/benchmarks/alias-bench
./src/benchmarks/json-render-bench ../src/benchmarks/portugal_to_korea.json
./src/benchmarks/match-bench ../test/data/ch/monaco.osrm
./src/benchmarks/match-bench ../test/data/ch/monaco.osrm ch
./src/benchmarks/match-bench ../test/data/mld/monaco.osrm mld
./src/benchmarks/packedvector-bench
./src/benchmarks/rtree-bench ../test/data/monaco.osrm.ramIndex ../test/data/monaco.osrm.fileIndex ../test/data/monaco.osrm.nbg_nodes
popd
- name: Use Node 18
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
uses: actions/setup-node@v3
with:
node-version: 18
- name: Run Node package tests on Node 18
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
run: |
node --version
npm run nodejs-tests
- name: Use Node 20
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == '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' }}
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
run: |
node --version
npm run nodejs-tests
- name: Use Node latest
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
uses: actions/setup-node@v3
with:
node-version: latest
- name: Run Node package tests on Node-latest
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
run: |
node --version
npm run nodejs-tests
@@ -585,12 +572,12 @@ jobs:
name: logs
path: test/logs/
- name: Generate code coverage
if: ${{ matrix.ENABLE_COVERAGE == 'ON' }}
run: |
lcov --directory . --capture --output-file coverage.info # capture coverage info
lcov --remove coverage.info '/usr/*' --output-file coverage.info # filter out system
lcov --list coverage.info #debug info
# - name: Generate code coverage
# if: ${{ matrix.ENABLE_COVERAGE == 'ON' }}
# run: |
# lcov --directory . --capture --output-file coverage.info # capture coverage info
# lcov --remove coverage.info '/usr/*' --output-file coverage.info # filter out system
# lcov --list coverage.info #debug info
# # Uploading report to CodeCov
# - name: Upload code coverage
@@ -601,15 +588,6 @@ jobs:
# name: codecov-osrm-backend
# fail_ci_if_error: true
# verbose: true
- name: Check Apple Silicon binary
if: ${{ matrix.ENABLE_APPLE_SILICON == 'ON' }}
run: |
ARCH=$(file ./lib/binding/node_osrm.node | awk '{printf $NF}')
if [[ "$ARCH" != "arm64" ]]; then
file ./lib/binding/node_osrm.node
>&2 echo "Wrong architecture!"
exit 1
fi
- name: Build Node package
if: ${{ matrix.build_node_package }}
run: ./scripts/ci/node_package.sh
+8
View File
@@ -12,10 +12,14 @@
- 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)
- ADDED: Add 'load directly' mode to default Cucumber test suite. [#6663](https://github.com/Project-OSRM/osrm-backend/pull/6663)
- CHANGED: Fix compilation for Boost 1.85.0 [#6856](https://github.com/Project-OSRM/osrm-backend/pull/6856)
- CHANGED: Drop support for Node 16 [#6855](https://github.com/Project-OSRM/osrm-backend/pull/6855)
- REMOVED: Remove unused AppVeyor files [#6860](https://github.com/Project-OSRM/osrm-backend/pull/6860)
- CHANGED: Upgrade clang-format to version 15 [#6859](https://github.com/Project-OSRM/osrm-backend/pull/6859)
- NodeJS:
- CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452)
- Misc:
- CHANGED: Update Conan Boost version to 1.85.0. [#6868](https://github.com/Project-OSRM/osrm-backend/pull/6868)
- FIXED: Fix an error in a RouteParameters AnnotationsType operator overload. [#6646](https://github.com/Project-OSRM/osrm-backend/pull/6646)
- ADDED: Add support for "unlimited" to be passed as a value for the default-radius and max-matching-radius flags. [#6599](https://github.com/Project-OSRM/osrm-backend/pull/6599)
- CHANGED: Allow -1.0 as unlimited for default_radius value. [#6599](https://github.com/Project-OSRM/osrm-backend/pull/6599)
@@ -41,6 +45,10 @@
- FIXED: Fix adding traffic signal penalties during compression [#6419](https://github.com/Project-OSRM/osrm-backend/pull/6419)
- FIXED: Correctly handle compressed traffic signals. [#6724](https://github.com/Project-OSRM/osrm-backend/pull/6724)
- FIXED: Fix bug when searching for maneuver overrides [#6739](https://github.com/Project-OSRM/osrm-backend/pull/6739)
- FIXED: Remove force-loop checks for routes with u-turns [#6858](https://github.com/Project-OSRM/osrm-backend/pull/6858)
- FIXED: Correctly check runtime search conditions for forcing routing steps [#6866](https://github.com/Project-OSRM/osrm-backend/pull/6866)
- Map Matching:
- CHANGED: Optimise path distance calculation in MLD map matching. [#6876](https://github.com/Project-OSRM/osrm-backend/pull/6876)
- Debug tiles:
- FIXED: Ensure speed layer features have unique ids. [#6726](https://github.com/Project-OSRM/osrm-backend/pull/6726)
+5 -8
View File
@@ -42,16 +42,13 @@ if (ENABLE_CLANG_TIDY)
message(FATAL_ERROR "ENABLE_CLANG_TIDY is ON but clang-tidy is not found!")
else()
message(STATUS "Found clang-tidy at ${CLANG_TIDY_COMMAND}")
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND};--warnings-as-errors=*")
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND};--warnings-as-errors=*;--header-filter=.*")
endif()
endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# be compatible with version handling before cmake 3.x
if (POLICY CMP0048)
cmake_policy(SET CMP0048 OLD)
endif()
if (POLICY CMP0057)
cmake_policy(SET CMP0057 NEW)
endif()
@@ -118,7 +115,7 @@ include(GNUInstallDirs)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
message(STATUS "Building on a 64 bit system")
else()
message(STATUS "Building on a 32 bit system")
message(FATAL_ERROR "Building on a 32 bit system is not supported")
endif()
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/)
@@ -226,7 +223,7 @@ endif()
set(MAYBE_COVERAGE_LIBRARIES "")
if (ENABLE_COVERAGE)
if (NOT CMAKE_BUILD_TYPE MATCHES "Debug")
message(ERROR "ENABLE_COVERAGE=ON only make sense with a Debug build")
message(ERROR "ENABLE_COVERAGE=ON only makes sense with a Debug build")
endif()
message(STATUS "Enabling coverage")
set(MAYBE_COVERAGE_LIBRARIES "-lgcov")
@@ -312,7 +309,7 @@ add_subdirectory(${FLATBUFFERS_SRC_DIR}
${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build
EXCLUDE_FROM_ALL)
set(FMT_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/fmt-9.1.0/include")
set(FMT_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/fmt/include")
add_compile_definitions(FMT_HEADER_ONLY)
include_directories(SYSTEM ${FMT_INCLUDE_DIR})
@@ -333,7 +330,7 @@ if(ENABLE_CONAN)
conan_check(REQUIRED)
set(CONAN_BOOST_VERSION "1.79.0@#96e4902111a2e343a8ba0aa95391bb58")
set(CONAN_BOOST_VERSION "1.85.0@#14265ec82b25d91305bbb3b30d3357f8")
set(CONAN_BZIP2_VERSION "1.0.8@#d1b2d5816f25865acf978501dff1f897")
set(CONAN_EXPAT_VERSION "2.2.10@#916908d4a570ad839edd25322c3268cd")
set(CONAN_LUA_VERSION "5.4.4@#3ec62efc37cd0a5d80b9e5cb35277360")
+1 -1
View File
@@ -10,7 +10,7 @@ You can add a :+1: emoji reaction to the issue if you want to express interest i
# Developer
We use `clang-format` version `3.8` to consistently format the code base. There is a helper script under `scripts/format.sh`.
We use `clang-format` version `15` to consistently format the code base. There is a helper script under `scripts/format.sh`.
The format is automatically checked by the `mason-linux-release` job of a Travis CI build.
To save development time a local hook `.git/hooks/pre-push`
```
-15
View File
@@ -1,15 +0,0 @@
os: Visual Studio 2019
# clone directory
clone_folder: c:\projects\osrm
platform: x64
# no-op for the time being until someone with access to GitHub checks settings will remove integration with AppVeyor
# https://github.com/Project-OSRM/osrm-backend/pull/6312#issuecomment-1217237055
build_script:
- EXIT 0
branches:
only:
- master
-32
View File
@@ -1,32 +0,0 @@
@ECHO OFF
SETLOCAL
SET EL=0
ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET PLATFORM=x64
SET CONFIGURATION=Release
::SET LOCAL_DEV=1
FOR /F "tokens=*" %%i in ('git rev-parse --abbrev-ref HEAD') do SET APPVEYOR_REPO_BRANCH=%%i
ECHO APPVEYOR_REPO_BRANCH^: %APPVEYOR_REPO_BRANCH%
SET PATH=C:\Program Files\7-Zip;%PATH%
powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
CALL appveyor-build.bat
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
GOTO DONE
:ERROR
ECHO ~~~~~~~~~~~~~~~~~~~~~~ ERROR %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ECHO ERRORLEVEL^: %ERRORLEVEL%
SET EL=%ERRORLEVEL%
:DONE
ECHO ~~~~~~~~~~~~~~~~~~~~~~ DONE %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EXIT /b %EL%
+101
View File
@@ -0,0 +1,101 @@
@routing @testbot @via
Feature: Force routing steps
Background:
Given the profile "testbot"
Scenario: Direct routes with waypoints on same edge
Given the node map
"""
1 2
a-------b
| |
d-------c
| |
e-------f
3 4
"""
And the ways
| nodes | oneway |
| ab | no |
| ad | no |
| bc | no |
| cf | no |
| dc | no |
| de | no |
| ef | yes |
When I route I should get
| waypoints | approaches | weight | route |
| 1,2 | | 20 | ab,ab |
| 1,2 | curb curb | 100 | ab,ad,dc,bc,ab |
| 2,1 | | 20 | ab,ab |
| 2,1 | opposite opposite | 100 | ab,bc,dc,ad,ab |
| 3,4 | | 20 | ef,ef |
| 4,3 | | 100 | ef,cf,dc,de,ef |
Scenario: Via routes with waypoints on same edge
Given the node map
"""
1 2
a-------b
| |
d-5-----c
| |
e-------f
3 4
"""
And the ways
| nodes | oneway |
| ab | no |
| ad | no |
| bc | no |
| cf | no |
| dc | no |
| de | no |
| ef | yes |
When I route I should get
| waypoints | approaches | weight | route |
| 5,1,2 | | 59.8 | dc,ad,ab,ab,ab |
| 5,1,2 | unrestricted curb curb | 180.2 | dc,bc,ab,ab,ab,ad,dc,bc,ab |
| 5,2,1 | | 80.2 | dc,bc,ab,ab,ab |
| 5,2,1 | unrestricted opposite opposite | 159.8 | dc,ad,ab,ab,ab,bc,dc,ad,ab |
| 5,3,4 | | 59.8 | dc,de,ef,ef,ef |
| 5,4,3 | | 159.8 | dc,de,ef,ef,ef,cf,dc,de,ef |
Scenario: [U-turns allowed] Via routes with waypoints on same edge
Given the node map
"""
1 2
a-------b
| |
d-5-----c
| |
e-------f
3 4
"""
And the ways
| nodes | oneway |
| ab | no |
| ad | no |
| bc | no |
| cf | no |
| dc | no |
| de | no |
| ef | yes |
And the query options
| continue_straight | false |
When I route I should get
| waypoints | approaches | weight | route |
| 5,1,2 | | 59.8 | dc,ad,ab,ab,ab |
| 5,1,2 | unrestricted curb curb | 180.2 | dc,bc,ab,ab,ab,ad,dc,bc,ab |
| 5,2,1 | | 79.8 | dc,ad,ab,ab,ab,ab |
| 5,2,1 | unrestricted opposite opposite | 159.8 | dc,ad,ab,ab,ab,bc,dc,ad,ab |
| 5,3,4 | | 59.8 | dc,de,ef,ef,ef |
| 5,4,3 | | 159.8 | dc,de,ef,ef,ef,cf,dc,de,ef |
@@ -61,10 +61,12 @@ inline auto contractExcludableGraph(ContractorGraph contractor_graph_,
// Add all non-core edges to container
{
auto non_core_edges = toEdges<QueryEdge>(contractor_graph);
auto new_end =
std::remove_if(non_core_edges.begin(), non_core_edges.end(), [&](const auto &edge) {
return is_shared_core[edge.source] && is_shared_core[edge.target];
});
auto new_end = std::remove_if(non_core_edges.begin(),
non_core_edges.end(),
[&](const auto &edge) {
return is_shared_core[edge.source] &&
is_shared_core[edge.target];
});
non_core_edges.resize(new_end - non_core_edges.begin());
edge_container.Insert(std::move(non_core_edges));
@@ -75,8 +77,8 @@ inline auto contractExcludableGraph(ContractorGraph contractor_graph_,
}
// Extract core graph for further contraction
shared_core_graph = contractor_graph.Filter(
[&is_shared_core](const NodeID node) { return is_shared_core[node]; });
shared_core_graph = contractor_graph.Filter([&is_shared_core](const NodeID node)
{ return is_shared_core[node]; });
}
for (const auto &filter : filters)
@@ -89,37 +89,40 @@ struct ContractedEdgeContainer
// Remove all edges that are contained in the old set of edges and set the appropriate flag.
auto new_end =
std::remove_if(new_edges.begin(), new_edges.end(), [&](const QueryEdge &edge) {
// check if the new edge would be sorted before the currend old edge
// if so it is not contained yet in the set of old edges
if (edge_iter == edge_end || mergeCompare(edge, *edge_iter))
{
return false;
}
std::remove_if(new_edges.begin(),
new_edges.end(),
[&](const QueryEdge &edge)
{
// check if the new edge would be sorted before the currend old edge
// if so it is not contained yet in the set of old edges
if (edge_iter == edge_end || mergeCompare(edge, *edge_iter))
{
return false;
}
// find the first old edge that is equal or greater then the new edge
while (edge_iter != edge_end && mergeCompare(*edge_iter, edge))
{
BOOST_ASSERT(flags_iter != flags.end());
edge_iter++;
flags_iter++;
}
// find the first old edge that is equal or greater then the new edge
while (edge_iter != edge_end && mergeCompare(*edge_iter, edge))
{
BOOST_ASSERT(flags_iter != flags.end());
edge_iter++;
flags_iter++;
}
// all new edges will be sorted after the old edges
if (edge_iter == edge_end)
{
return false;
}
// all new edges will be sorted after the old edges
if (edge_iter == edge_end)
{
return false;
}
BOOST_ASSERT(edge_iter != edge_end);
if (mergable(edge, *edge_iter))
{
*flags_iter = *flags_iter | flag;
return true;
}
BOOST_ASSERT(mergeCompare(edge, *edge_iter));
return false;
});
BOOST_ASSERT(edge_iter != edge_end);
if (mergable(edge, *edge_iter))
{
*flags_iter = *flags_iter | flag;
return true;
}
BOOST_ASSERT(mergeCompare(edge, *edge_iter));
return false;
});
// append new edges
edges.insert(edges.end(), new_edges.begin(), new_end);
@@ -132,10 +135,10 @@ struct ContractedEdgeContainer
// enforce sorting for next merge step
std::vector<unsigned> ordering(edges_size);
std::iota(ordering.begin(), ordering.end(), 0);
tbb::parallel_sort(
ordering.begin(), ordering.end(), [&](const auto lhs_idx, const auto rhs_idx) {
return mergeCompare(edges[lhs_idx], edges[rhs_idx]);
});
tbb::parallel_sort(ordering.begin(),
ordering.end(),
[&](const auto lhs_idx, const auto rhs_idx)
{ return mergeCompare(edges[lhs_idx], edges[rhs_idx]); });
auto permutation = util::orderingToPermutation(ordering);
util::inplacePermutation(edges.begin(), edges.end(), permutation);
+2 -1
View File
@@ -122,7 +122,8 @@ class CellCustomizer
for (std::size_t level = 1; level < partition.GetNumberOfLevels(); ++level)
{
tbb::parallel_for(tbb::blocked_range<std::size_t>(0, partition.GetNumberOfCells(level)),
[&](const tbb::blocked_range<std::size_t> &range) {
[&](const tbb::blocked_range<std::size_t> &range)
{
auto &heap = heaps.local();
for (auto id = range.begin(), end = range.end(); id != end; ++id)
{
+6 -7
View File
@@ -40,10 +40,10 @@ class BaseAPI
util::json::Array waypoints;
waypoints.values.resize(parameters.coordinates.size());
boost::range::transform(
waypoint_candidates,
waypoints.values.begin(),
[this](const PhantomNodeCandidates &candidates) { return MakeWaypoint(candidates); });
boost::range::transform(waypoint_candidates,
waypoints.values.begin(),
[this](const PhantomNodeCandidates &candidates)
{ return MakeWaypoint(candidates); });
return waypoints;
}
@@ -104,9 +104,8 @@ class BaseAPI
std::transform(waypoint_candidates.begin(),
waypoint_candidates.end(),
waypoints.begin(),
[this, builder](const PhantomNodeCandidates &candidates) {
return MakeWaypoint(builder, candidates)->Finish();
});
[this, builder](const PhantomNodeCandidates &candidates)
{ return MakeWaypoint(builder, candidates)->Finish(); });
return builder->CreateVector(waypoints);
}
+2 -1
View File
@@ -112,7 +112,8 @@ struct BaseParameters
(approaches.empty() || approaches.size() == coordinates.size()) &&
std::all_of(bearings.begin(),
bearings.end(),
[](const boost::optional<Bearing> &bearing_and_range) {
[](const boost::optional<Bearing> &bearing_and_range)
{
if (bearing_and_range)
{
return bearing_and_range->IsValid();
+4 -3
View File
@@ -52,9 +52,10 @@ class MatchAPI final : public RouteAPI
data_version_string = fb_result.CreateString(data_timestamp);
}
auto response = MakeFBResponse(sub_routes, fb_result, [this, &fb_result, &sub_matchings]() {
return MakeTracepoints(fb_result, sub_matchings);
});
auto response = MakeFBResponse(sub_routes,
fb_result,
[this, &fb_result, &sub_matchings]()
{ return MakeTracepoints(fb_result, sub_matchings); });
if (!data_timestamp.empty())
{
+2 -2
View File
@@ -67,7 +67,7 @@ struct MatchParameters : public RouteParameters
MatchParameters(const std::vector<unsigned> &timestamps_,
GapsType gaps_,
bool tidy_,
Args &&... args_)
Args &&...args_)
: MatchParameters(timestamps_, gaps_, tidy_, {}, std::forward<Args>(args_)...)
{
}
@@ -77,7 +77,7 @@ struct MatchParameters : public RouteParameters
GapsType gaps_,
bool tidy_,
const std::vector<std::size_t> &waypoints_,
Args &&... args_)
Args &&...args_)
: RouteParameters{std::forward<Args>(args_)..., waypoints_}, timestamps{std::move(
timestamps_)},
gaps(gaps_), tidy(tidy_)
+14 -13
View File
@@ -57,20 +57,20 @@ class NearestAPI final : public BaseAPI
{
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
waypoints.resize(phantom_nodes.front().size());
std::transform(
phantom_nodes.front().begin(),
phantom_nodes.front().end(),
waypoints.begin(),
[this, &fb_result](const PhantomNodeWithDistance &phantom_with_distance) {
auto &phantom_node = phantom_with_distance.phantom_node;
std::transform(phantom_nodes.front().begin(),
phantom_nodes.front().end(),
waypoints.begin(),
[this, &fb_result](const PhantomNodeWithDistance &phantom_with_distance)
{
auto &phantom_node = phantom_with_distance.phantom_node;
auto node_values = MakeNodes(phantom_node);
fbresult::Uint64Pair nodes{node_values.first, node_values.second};
auto node_values = MakeNodes(phantom_node);
fbresult::Uint64Pair nodes{node_values.first, node_values.second};
auto waypoint = MakeWaypoint(&fb_result, {phantom_node});
waypoint->add_nodes(&nodes);
return waypoint->Finish();
});
auto waypoint = MakeWaypoint(&fb_result, {phantom_node});
waypoint->add_nodes(&nodes);
return waypoint->Finish();
});
waypoints_vector = fb_result.CreateVector(waypoints);
}
@@ -94,7 +94,8 @@ class NearestAPI final : public BaseAPI
std::transform(phantom_nodes.front().begin(),
phantom_nodes.front().end(),
waypoints.values.begin(),
[this](const PhantomNodeWithDistance &phantom_with_distance) {
[this](const PhantomNodeWithDistance &phantom_with_distance)
{
auto &phantom_node = phantom_with_distance.phantom_node;
auto waypoint = MakeWaypoint({phantom_node});
+61 -50
View File
@@ -77,9 +77,10 @@ class RouteAPI : public BaseAPI
}
auto response =
MakeFBResponse(raw_routes, fb_result, [this, &waypoint_candidates, &fb_result]() {
return BaseAPI::MakeWaypoints(&fb_result, waypoint_candidates);
});
MakeFBResponse(raw_routes,
fb_result,
[this, &waypoint_candidates, &fb_result]()
{ return BaseAPI::MakeWaypoints(&fb_result, waypoint_candidates); });
if (!data_timestamp.empty())
{
@@ -171,10 +172,15 @@ class RouteAPI : public BaseAPI
}
std::vector<fbresult::Position> coordinates;
coordinates.resize(std::distance(begin, end));
std::transform(begin, end, coordinates.begin(), [](const Coordinate &c) {
return fbresult::Position{static_cast<float>(util::toFloating(c.lon).__value),
static_cast<float>(util::toFloating(c.lat).__value)};
});
std::transform(begin,
end,
coordinates.begin(),
[](const Coordinate &c)
{
return fbresult::Position{
static_cast<float>(util::toFloating(c.lon).__value),
static_cast<float>(util::toFloating(c.lat).__value)};
});
return builder.CreateVectorOfStructs(coordinates);
}
@@ -354,9 +360,8 @@ class RouteAPI : public BaseAPI
std::transform(leg.steps.begin(),
leg.steps.end(),
legSteps.begin(),
[this, &fb_result, &leg_geometry](auto &step) {
return this->MakeFBStep(fb_result, leg_geometry, step);
});
[this, &fb_result, &leg_geometry](auto &step)
{ return this->MakeFBStep(fb_result, leg_geometry, step); });
}
auto steps_vector = fb_result.CreateVector(legSteps);
@@ -441,7 +446,8 @@ class RouteAPI : public BaseAPI
speed =
GetAnnotations<float>(fb_result,
leg_geometry,
[&prev_speed](const guidance::LegGeometry::Annotation &anno) {
[&prev_speed](const guidance::LegGeometry::Annotation &anno)
{
if (anno.duration < std::numeric_limits<float>::min())
{
return prev_speed;
@@ -459,37 +465,37 @@ class RouteAPI : public BaseAPI
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> duration;
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
{
duration = GetAnnotations<uint32_t>(
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.duration;
});
duration = GetAnnotations<uint32_t>(fb_result,
leg_geometry,
[](const guidance::LegGeometry::Annotation &anno)
{ return anno.duration; });
}
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> distance;
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
{
distance = GetAnnotations<uint32_t>(
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.distance;
});
distance = GetAnnotations<uint32_t>(fb_result,
leg_geometry,
[](const guidance::LegGeometry::Annotation &anno)
{ return anno.distance; });
}
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> weight;
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
{
weight = GetAnnotations<uint32_t>(
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.weight;
});
weight = GetAnnotations<uint32_t>(fb_result,
leg_geometry,
[](const guidance::LegGeometry::Annotation &anno)
{ return anno.weight; });
}
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> datasources;
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
{
datasources = GetAnnotations<uint32_t>(
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.datasource;
});
datasources = GetAnnotations<uint32_t>(fb_result,
leg_geometry,
[](const guidance::LegGeometry::Annotation &anno)
{ return anno.datasource; });
}
std::vector<uint32_t> nodes;
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
@@ -653,7 +659,8 @@ class RouteAPI : public BaseAPI
step.intersections.begin(),
step.intersections.end(),
intersections.begin(),
[&fb_result, this](const guidance::IntermediateIntersection &intersection) {
[&fb_result, this](const guidance::IntermediateIntersection &intersection)
{
std::vector<flatbuffers::Offset<fbresult::Lane>> lanes;
if (json::detail::hasValidLanes(intersection))
{
@@ -681,11 +688,11 @@ class RouteAPI : public BaseAPI
auto bearings_vector = fb_result.CreateVector(intersection.bearings);
std::vector<flatbuffers::Offset<flatbuffers::String>> classes;
classes.resize(intersection.classes.size());
std::transform(
intersection.classes.begin(),
intersection.classes.end(),
classes.begin(),
[&fb_result](const std::string &cls) { return fb_result.CreateString(cls); });
std::transform(intersection.classes.begin(),
intersection.classes.end(),
classes.begin(),
[&fb_result](const std::string &cls)
{ return fb_result.CreateString(cls); });
auto classes_vector = fb_result.CreateVector(classes);
auto entry_vector = fb_result.CreateVector(intersection.entry);
@@ -720,9 +727,10 @@ class RouteAPI : public BaseAPI
std::vector<util::json::Value> step_geometries;
const auto total_step_count =
std::accumulate(legs.begin(), legs.end(), 0, [](const auto &v, const auto &leg) {
return v + leg.steps.size();
});
std::accumulate(legs.begin(),
legs.end(),
0,
[](const auto &v, const auto &leg) { return v + leg.steps.size(); });
step_geometries.reserve(total_step_count);
for (const auto idx : util::irange<std::size_t>(0UL, legs.size()))
@@ -733,7 +741,8 @@ class RouteAPI : public BaseAPI
legs[idx].steps.begin(),
legs[idx].steps.end(),
std::back_inserter(step_geometries),
[this, &leg_geometry](const guidance::RouteStep &step) {
[this, &leg_geometry](const guidance::RouteStep &step)
{
if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
{
return static_cast<util::json::Value>(json::makePolyline<100000>(
@@ -778,7 +787,9 @@ class RouteAPI : public BaseAPI
{
double prev_speed = 0;
annotation.values["speed"] = GetAnnotations(
leg_geometry, [&prev_speed](const guidance::LegGeometry::Annotation &anno) {
leg_geometry,
[&prev_speed](const guidance::LegGeometry::Annotation &anno)
{
if (anno.duration < std::numeric_limits<double>::min())
{
return prev_speed;
@@ -794,17 +805,17 @@ class RouteAPI : public BaseAPI
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
{
annotation.values["duration"] = GetAnnotations(
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.duration;
});
annotation.values["duration"] =
GetAnnotations(leg_geometry,
[](const guidance::LegGeometry::Annotation &anno)
{ return anno.duration; });
}
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
{
annotation.values["distance"] = GetAnnotations(
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.distance;
});
annotation.values["distance"] =
GetAnnotations(leg_geometry,
[](const guidance::LegGeometry::Annotation &anno)
{ return anno.distance; });
}
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
{
@@ -814,10 +825,10 @@ class RouteAPI : public BaseAPI
}
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
{
annotation.values["datasources"] = GetAnnotations(
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
return anno.datasource;
});
annotation.values["datasources"] =
GetAnnotations(leg_geometry,
[](const guidance::LegGeometry::Annotation &anno)
{ return anno.datasource; });
}
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
{
+8 -8
View File
@@ -83,7 +83,7 @@ struct RouteParameters : public BaseParameters
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
Args &&... args_)
Args &&...args_)
// Once we perfectly-forward `args` (see #2990) this constructor can delegate to the one
// below.
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
@@ -101,7 +101,7 @@ struct RouteParameters : public BaseParameters
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
Args &&... args_)
Args &&...args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
@@ -119,7 +119,7 @@ struct RouteParameters : public BaseParameters
const GeometriesType geometries_,
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
Args &&... args_)
Args &&...args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u},
annotations{annotations_ != AnnotationsType::None}, annotations_type{annotations_},
@@ -137,7 +137,7 @@ struct RouteParameters : public BaseParameters
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
std::vector<std::size_t> waypoints_,
const Args &&... args_)
const Args &&...args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
@@ -155,7 +155,7 @@ struct RouteParameters : public BaseParameters
const OverviewType overview_,
const boost::optional<bool> continue_straight_,
std::vector<std::size_t> waypoints_,
Args &&... args_)
Args &&...args_)
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_ !=
AnnotationsType::None},
@@ -180,9 +180,9 @@ struct RouteParameters : public BaseParameters
const auto coordinates_ok = coordinates.size() >= 2;
const auto base_params_ok = BaseParameters::IsValid();
const auto valid_waypoints =
std::all_of(waypoints.begin(), waypoints.end(), [this](const auto &w) {
return w < coordinates.size();
});
std::all_of(waypoints.begin(),
waypoints.end(),
[this](const auto &w) { return w < coordinates.size(); });
return coordinates_ok && base_params_ok && valid_waypoints;
}
};
+50 -38
View File
@@ -245,9 +245,8 @@ class TableAPI final : public BaseAPI
boost::range::transform(candidates,
std::back_inserter(waypoints),
[this, &builder](const PhantomNodeCandidates &candidates) {
return BaseAPI::MakeWaypoint(&builder, candidates)->Finish();
});
[this, &builder](const PhantomNodeCandidates &candidates)
{ return BaseAPI::MakeWaypoint(&builder, candidates)->Finish(); });
return builder.CreateVector(waypoints);
}
@@ -261,7 +260,8 @@ class TableAPI final : public BaseAPI
boost::range::transform(
indices,
std::back_inserter(waypoints),
[this, &builder, &candidates](const std::size_t idx) {
[this, &builder, &candidates](const std::size_t idx)
{
BOOST_ASSERT(idx < candidates.size());
return BaseAPI::MakeWaypoint(&builder, candidates[idx])->Finish();
});
@@ -274,14 +274,17 @@ class TableAPI final : public BaseAPI
{
std::vector<float> distance_table;
distance_table.resize(values.size());
std::transform(
values.begin(), values.end(), distance_table.begin(), [](const EdgeDuration duration) {
if (duration == MAXIMAL_EDGE_DURATION)
{
return 0.;
}
return from_alias<double>(duration) / 10.;
});
std::transform(values.begin(),
values.end(),
distance_table.begin(),
[](const EdgeDuration duration)
{
if (duration == MAXIMAL_EDGE_DURATION)
{
return 0.;
}
return from_alias<double>(duration) / 10.;
});
return builder.CreateVector(distance_table);
}
@@ -291,14 +294,17 @@ class TableAPI final : public BaseAPI
{
std::vector<float> duration_table;
duration_table.resize(values.size());
std::transform(
values.begin(), values.end(), duration_table.begin(), [](const EdgeDistance distance) {
if (distance == INVALID_EDGE_DISTANCE)
{
return 0.;
}
return std::round(from_alias<double>(distance) * 10) / 10.;
});
std::transform(values.begin(),
values.end(),
duration_table.begin(),
[](const EdgeDistance distance)
{
if (distance == INVALID_EDGE_DISTANCE)
{
return 0.;
}
return std::round(from_alias<double>(distance) * 10) / 10.;
});
return builder.CreateVector(duration_table);
}
@@ -308,11 +314,13 @@ class TableAPI final : public BaseAPI
{
std::vector<uint32_t> fb_table;
fb_table.reserve(fallback_speed_cells.size());
std::for_each(
fallback_speed_cells.begin(), fallback_speed_cells.end(), [&](const auto &cell) {
fb_table.push_back(cell.row);
fb_table.push_back(cell.column);
});
std::for_each(fallback_speed_cells.begin(),
fallback_speed_cells.end(),
[&](const auto &cell)
{
fb_table.push_back(cell.row);
fb_table.push_back(cell.column);
});
return builder.CreateVector(fb_table);
}
@@ -325,9 +333,8 @@ class TableAPI final : public BaseAPI
boost::range::transform(candidates,
std::back_inserter(json_waypoints.values),
[this](const PhantomNodeCandidates &candidates) {
return BaseAPI::MakeWaypoint(candidates);
});
[this](const PhantomNodeCandidates &candidates)
{ return BaseAPI::MakeWaypoint(candidates); });
return json_waypoints;
}
@@ -338,7 +345,8 @@ class TableAPI final : public BaseAPI
json_waypoints.values.reserve(indices.size());
boost::range::transform(indices,
std::back_inserter(json_waypoints.values),
[this, &candidates](const std::size_t idx) {
[this, &candidates](const std::size_t idx)
{
BOOST_ASSERT(idx < candidates.size());
return BaseAPI::MakeWaypoint(candidates[idx]);
});
@@ -359,7 +367,8 @@ class TableAPI final : public BaseAPI
std::transform(row_begin_iterator,
row_end_iterator,
json_row.values.begin(),
[](const EdgeDuration duration) {
[](const EdgeDuration duration)
{
if (duration == MAXIMAL_EDGE_DURATION)
{
return util::json::Value(util::json::Null());
@@ -387,7 +396,8 @@ class TableAPI final : public BaseAPI
std::transform(row_begin_iterator,
row_end_iterator,
json_row.values.begin(),
[](const EdgeDistance distance) {
[](const EdgeDistance distance)
{
if (distance == INVALID_EDGE_DISTANCE)
{
return util::json::Value(util::json::Null());
@@ -405,13 +415,15 @@ class TableAPI final : public BaseAPI
MakeEstimatesTable(const std::vector<TableCellRef> &fallback_speed_cells) const
{
util::json::Array json_table;
std::for_each(
fallback_speed_cells.begin(), fallback_speed_cells.end(), [&](const auto &cell) {
util::json::Array row;
row.values.push_back(util::json::Number(cell.row));
row.values.push_back(util::json::Number(cell.column));
json_table.values.push_back(std::move(row));
});
std::for_each(fallback_speed_cells.begin(),
fallback_speed_cells.end(),
[&](const auto &cell)
{
util::json::Array row;
row.values.push_back(util::json::Number(cell.row));
row.values.push_back(util::json::Number(cell.column));
json_table.values.push_back(std::move(row));
});
return json_table;
}
+3 -3
View File
@@ -81,7 +81,7 @@ struct TableParameters : public BaseParameters
template <typename... Args>
TableParameters(std::vector<std::size_t> sources_,
std::vector<std::size_t> destinations_,
Args &&... args_)
Args &&...args_)
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
destinations{std::move(destinations_)}
{
@@ -91,7 +91,7 @@ struct TableParameters : public BaseParameters
TableParameters(std::vector<std::size_t> sources_,
std::vector<std::size_t> destinations_,
const AnnotationsType annotations_,
Args &&... args_)
Args &&...args_)
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
destinations{std::move(destinations_)}, annotations{annotations_}
{
@@ -104,7 +104,7 @@ struct TableParameters : public BaseParameters
double fallback_speed_,
FallbackCoordinateType fallback_coordinate_type_,
double scale_factor_,
Args &&... args_)
Args &&...args_)
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
destinations{std::move(destinations_)}, fallback_speed{fallback_speed_},
fallback_coordinate_type{fallback_coordinate_type_}, annotations{annotations_},
+4 -4
View File
@@ -50,10 +50,10 @@ class TripAPI final : public RouteAPI
data_version_string = fb_result.CreateString(data_timestamp);
}
auto response =
MakeFBResponse(sub_routes, fb_result, [this, &fb_result, &sub_trips, &candidates]() {
return MakeWaypoints(fb_result, sub_trips, candidates);
});
auto response = MakeFBResponse(sub_routes,
fb_result,
[this, &fb_result, &sub_trips, &candidates]()
{ return MakeWaypoints(fb_result, sub_trips, candidates); });
if (!data_timestamp.empty())
{
+1 -1
View File
@@ -60,7 +60,7 @@ struct TripParameters : public RouteParameters
TripParameters(SourceType source_,
DestinationType destination_,
bool roundtrip_,
Args &&... args_)
Args &&...args_)
: RouteParameters{std::forward<Args>(args_)...}, source{source_},
destination{destination_}, roundtrip{roundtrip_}
{
@@ -440,9 +440,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
{
auto indexes = extractor::getClassIndexes(class_data);
std::vector<std::string> classes(indexes.size());
std::transform(indexes.begin(), indexes.end(), classes.begin(), [this](const auto index) {
return m_profile_properties->GetClassName(index);
});
std::transform(indexes.begin(),
indexes.end(),
classes.begin(),
[this](const auto index)
{ return m_profile_properties->GetClassName(index); });
return classes;
}
@@ -600,15 +602,19 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
auto found_range = std::equal_range(
m_maneuver_overrides.begin(), m_maneuver_overrides.end(), edge_based_node_id, Comp{});
std::for_each(found_range.first, found_range.second, [&](const auto &override) {
std::vector<NodeID> sequence(
m_maneuver_override_node_sequences.begin() + override.node_sequence_offset_begin,
m_maneuver_override_node_sequences.begin() + override.node_sequence_offset_end);
results.push_back(extractor::ManeuverOverride{std::move(sequence),
override.instruction_node,
override.override_type,
override.direction});
});
std::for_each(found_range.first,
found_range.second,
[&](const auto &override)
{
std::vector<NodeID> sequence(m_maneuver_override_node_sequences.begin() +
override.node_sequence_offset_begin,
m_maneuver_override_node_sequences.begin() +
override.node_sequence_offset_end);
results.push_back(extractor::ManeuverOverride{std::move(sequence),
override.instruction_node,
override.override_type,
override.direction});
});
return results;
}
};
+36 -27
View File
@@ -60,7 +60,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
auto results = rtree.Nearest(
input_coordinate,
[this, approach, &input_coordinate, &bearing_with_range, &use_all_edges](
const CandidateSegment &segment) {
const CandidateSegment &segment)
{
auto valid = CheckSegmentExclude(segment) &&
CheckApproach(input_coordinate, segment, approach) &&
(use_all_edges ? HasValidEdge(segment, *use_all_edges)
@@ -70,7 +71,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
return valid;
},
[this, &max_distance, &max_results, input_coordinate](const std::size_t num_results,
const CandidateSegment &segment) {
const CandidateSegment &segment)
{
return (max_results && num_results >= *max_results) ||
(max_distance && max_distance != -1.0 &&
CheckSegmentDistance(input_coordinate, segment, *max_distance));
@@ -107,7 +109,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
&big_component_coord,
&big_component_distance,
&use_all_edges,
&bearing_with_range](const CandidateSegment &segment) {
&bearing_with_range](const CandidateSegment &segment)
{
auto is_big_component = !IsTinyComponent(segment);
auto not_nearest =
has_nearest && segment.fixed_projected_coordinate != nearest_coord;
@@ -159,7 +162,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
return use_candidate;
},
[this, &has_big_component, &max_distance, input_coordinate, &big_component_distance](
const std::size_t /*num_results*/, const CandidateSegment &segment) {
const std::size_t /*num_results*/, const CandidateSegment &segment)
{
auto distance = GetSegmentDistance(input_coordinate, segment);
auto further_than_big_component = distance > big_component_distance;
auto no_more_candidates = has_big_component && further_than_big_component;
@@ -190,13 +194,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
PhantomNodeCandidates nearest_phantoms;
PhantomNodeCandidates big_component_phantoms;
const auto add_to_candidates = [this, &input_coordinate](PhantomNodeCandidates &candidates,
const EdgeData data) {
const auto add_to_candidates =
[this, &input_coordinate](PhantomNodeCandidates &candidates, const EdgeData data)
{
auto candidate_it =
std::find_if(candidates.begin(), candidates.end(), [&](const PhantomNode &node) {
return data.forward_segment_id.id == node.forward_segment_id.id &&
data.reverse_segment_id.id == node.reverse_segment_id.id;
});
std::find_if(candidates.begin(),
candidates.end(),
[&](const PhantomNode &node)
{
return data.forward_segment_id.id == node.forward_segment_id.id &&
data.reverse_segment_id.id == node.reverse_segment_id.id;
});
if (candidate_it == candidates.end())
{
// First candidate from this segment
@@ -259,17 +267,20 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
}
};
std::for_each(results.begin(), results.end(), [&](const CandidateSegment &segment) {
if (segment.fixed_projected_coordinate == nearest_coord)
{
add_to_candidates(nearest_phantoms, segment.data);
}
else
{
// Can only be from a big component for the alternative candidates
add_to_candidates(big_component_phantoms, segment.data);
}
});
std::for_each(results.begin(),
results.end(),
[&](const CandidateSegment &segment)
{
if (segment.fixed_projected_coordinate == nearest_coord)
{
add_to_candidates(nearest_phantoms, segment.data);
}
else
{
// Can only be from a big component for the alternative candidates
add_to_candidates(big_component_phantoms, segment.data);
}
});
return std::make_pair(std::move(nearest_phantoms), std::move(big_component_phantoms));
}
@@ -281,9 +292,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
std::transform(results.begin(),
results.end(),
distance_and_phantoms.begin(),
[this, &input_coordinate](const CandidateSegment &segment) {
return MakePhantomNode(input_coordinate, segment.data);
});
[this, &input_coordinate](const CandidateSegment &segment)
{ return MakePhantomNode(input_coordinate, segment.data); });
return distance_and_phantoms;
}
@@ -400,9 +410,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
}
// check phantom node segments validity
auto areSegmentsValid = [](auto first, auto last) -> bool {
return std::find(first, last, INVALID_SEGMENT_WEIGHT) == last;
};
auto areSegmentsValid = [](auto first, auto last) -> bool
{ return std::find(first, last, INVALID_SEGMENT_WEIGHT) == last; };
bool is_forward_valid_source =
areSegmentsValid(forward_weights.begin(), forward_weights.end());
bool is_forward_valid_target = areSegmentsValid(
+37 -28
View File
@@ -43,7 +43,8 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
const bool target_traversed_in_reverse)
{
// merges segments with same name id
const auto collapse_segments = [](std::vector<NamedSegment> &segments) {
const auto collapse_segments = [](std::vector<NamedSegment> &segments)
{
auto out = segments.begin();
auto end = segments.end();
@@ -75,7 +76,8 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
std::transform(route_data.begin(),
route_data.end(),
segments.begin(),
[&index, &facade](const PathData &point) {
[&index, &facade](const PathData &point)
{
return NamedSegment{point.duration_until_turn,
index++,
facade.GetNameIndex(point.from_edge_based_node)};
@@ -87,33 +89,37 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
if (target_duration > EdgeDuration{1})
segments.push_back({target_duration, index++, facade.GetNameIndex(target_node_id)});
// this makes sure that the segment with the lowest position comes first
std::sort(
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
return lhs.name_id < rhs.name_id ||
(lhs.name_id == rhs.name_id && lhs.position < rhs.position);
});
std::sort(segments.begin(),
segments.end(),
[](const NamedSegment &lhs, const NamedSegment &rhs)
{
return lhs.name_id < rhs.name_id ||
(lhs.name_id == rhs.name_id && lhs.position < rhs.position);
});
auto new_end = collapse_segments(segments);
segments.resize(new_end - segments.begin());
// Filter out segments with an empty name (name_id == 0)
new_end = std::remove_if(segments.begin(), segments.end(), [](const NamedSegment &segment) {
return segment.name_id == 0;
});
new_end = std::remove_if(segments.begin(),
segments.end(),
[](const NamedSegment &segment) { return segment.name_id == 0; });
segments.resize(new_end - segments.begin());
// sort descending
std::sort(
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
return lhs.duration > rhs.duration ||
(lhs.duration == rhs.duration && lhs.position < rhs.position);
});
std::sort(segments.begin(),
segments.end(),
[](const NamedSegment &lhs, const NamedSegment &rhs)
{
return lhs.duration > rhs.duration ||
(lhs.duration == rhs.duration && lhs.position < rhs.position);
});
// make sure the segments are sorted by position
segments.resize(std::min(segments.size(), SegmentNumber));
std::sort(
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
return lhs.position < rhs.position;
});
std::sort(segments.begin(),
segments.end(),
[](const NamedSegment &lhs, const NamedSegment &rhs)
{ return lhs.position < rhs.position; });
std::array<std::uint32_t, SegmentNumber> summary;
std::fill(summary.begin(), summary.end(), EMPTY_NAMEID);
@@ -138,7 +144,8 @@ inline std::string assembleSummary(const datafacade::BaseDataFacade &facade,
// transform a name_id into a string containing either the name, or -if the name is empty-
// the reference.
const auto name_id_to_string = [&](const NameID name_id) {
const auto name_id_to_string = [&](const NameID name_id)
{
const auto name = facade.GetNameForID(name_id);
if (!name.empty())
return std::string(name);
@@ -178,14 +185,16 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
const auto target_weight =
(target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight);
auto duration = std::accumulate(
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
return sum + from_alias<double>(data.duration_until_turn);
});
auto weight = std::accumulate(
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
return sum + from_alias<double>(data.weight_until_turn);
});
auto duration = std::accumulate(route_data.begin(),
route_data.end(),
0,
[](const double sum, const PathData &data)
{ return sum + from_alias<double>(data.duration_until_turn); });
auto weight = std::accumulate(route_data.begin(),
route_data.end(),
0,
[](const double sum, const PathData &data)
{ return sum + from_alias<double>(data.weight_until_turn); });
// s
// |
@@ -16,7 +16,7 @@ bool basicCollapsePreconditions(const RouteStepIterator first,
// Staggered intersection are very short zig-zags of a few meters.
// We do not want to announce these short left-rights or right-lefts:
// 
//  
// * -> b a -> *
// | or | becomes a -> b
// a -> * * -> b
@@ -26,7 +26,7 @@ bool isStaggeredIntersection(const RouteStepIterator step_prior_to_intersection,
// Two two turns following close after another, we can announce them as a U-Turn if both end up
// involving the same (segregated) road.
// 
//  
// b < - y
// | will be represented by at x, turn around instead of turn left at x, turn left at y
// a - > x
@@ -42,11 +42,11 @@ bool isNameOszillation(const RouteStepIterator step_prior_to_intersection,
// Sometimes, segments names don't match the perceived turns. We try to detect these additional
// name changes and issue a combined turn.
// 
//  
// | e |
// a - b - c
// d
// 
//  
// can have `a-b` as one name, `b-c-d` as a second. At `b` we would issue a new name, even though
// the road turns right after. The offset would only be there due to the broad road at `e`
bool maneuverPreceededByNameChange(const RouteStepIterator step_prior_to_intersection,
@@ -73,11 +73,11 @@ bool doubleChoiceless(const RouteStepIterator step_entering_intersection,
// Due to obvious detection, sometimes we can have straight turns followed by a different turn right
// next to each other. We combine both turns into one, if the second turn is without choice
// 
//  e
//  
//   e
// a - b - c
// ' d
// 
//  
// with a main road `abd`, the turn `continue straight` at `b` and `turn left at `c` will become a
// `turn left` at `b`
bool straightTurnFollowedByChoiceless(const RouteStepIterator step_entering_intersection,
+10 -7
View File
@@ -122,9 +122,8 @@ inline bool haveSameMode(const RouteStep &first, const RouteStep &second, const
// alias for readability
inline bool haveSameName(const RouteStep &lhs, const RouteStep &rhs)
{
const auto has_name_or_ref = [](auto const &step) {
return !step.name.empty() || !step.ref.empty();
};
const auto has_name_or_ref = [](auto const &step)
{ return !step.name.empty() || !step.ref.empty(); };
// make sure empty is not involved
if (!has_name_or_ref(lhs) || !has_name_or_ref(rhs))
@@ -151,12 +150,14 @@ inline bool haveSameName(const RouteStep &lhs, const RouteStep &rhs)
// alias for readability, both turn right | left
inline bool areSameSide(const RouteStep &lhs, const RouteStep &rhs)
{
const auto is_left = [](const RouteStep &step) {
const auto is_left = [](const RouteStep &step)
{
return hasModifier(step, osrm::guidance::DirectionModifier::Straight) ||
hasLeftModifier(step.maneuver.instruction);
};
const auto is_right = [](const RouteStep &step) {
const auto is_right = [](const RouteStep &step)
{
return hasModifier(step, osrm::guidance::DirectionModifier::Straight) ||
hasRightModifier(step.maneuver.instruction);
};
@@ -174,7 +175,8 @@ inline std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> st
// Two valid NO_TURNs exist in each leg in the form of Depart/Arrive
// keep valid instructions
const auto not_is_valid = [](const RouteStep &step) {
const auto not_is_valid = [](const RouteStep &step)
{
return step.maneuver.instruction == osrm::guidance::TurnInstruction::NO_TURN() &&
step.maneuver.waypoint_type == WaypointType::None;
};
@@ -225,7 +227,8 @@ inline double totalTurnAngle(const RouteStep &entry_step, const RouteStep &exit_
inline bool bearingsAreReversed(const double bearing_in, const double bearing_out)
{
// Nearly perfectly reversed angles have a difference close to 180 degrees (straight)
const double left_turn_angle = [&]() {
const double left_turn_angle = [&]()
{
if (0 <= bearing_out && bearing_out <= bearing_in)
return bearing_in - bearing_out;
return bearing_in + 360 - bearing_out;
@@ -20,14 +20,16 @@ template <typename Iter, typename Fn> inline Fn forEachRoundabout(Iter first, It
{
while (first != last)
{
const auto enter = std::find_if(first, last, [](const RouteStep &step) {
return entersRoundabout(step.maneuver.instruction);
});
const auto enter = std::find_if(first,
last,
[](const RouteStep &step)
{ return entersRoundabout(step.maneuver.instruction); });
// enter has to come before leave, otherwise: faulty data / partial roundabout, skip those
const auto leave = std::find_if(enter, last, [](const RouteStep &step) {
return leavesRoundabout(step.maneuver.instruction);
});
const auto leave = std::find_if(enter,
last,
[](const RouteStep &step)
{ return leavesRoundabout(step.maneuver.instruction); });
// No roundabouts, or partial one (like start / end inside a roundabout)
if (enter == last || leave == last)
+4 -4
View File
@@ -259,10 +259,10 @@ inline util::Coordinate candidatesInputLocation(const PhantomNodeCandidates &can
inline bool candidatesHaveComponent(const PhantomNodeCandidates &candidates, uint32_t component_id)
{
return std::any_of(
candidates.begin(), candidates.end(), [component_id](const PhantomNode &node) {
return node.component.id == component_id;
});
return std::any_of(candidates.begin(),
candidates.end(),
[component_id](const PhantomNode &node)
{ return node.component.id == component_id; });
}
struct PhantomEndpoints
+35 -35
View File
@@ -33,10 +33,10 @@ class BasePlugin
bool CheckAllCoordinates(const std::vector<util::Coordinate> &coordinates) const
{
return !std::any_of(
std::begin(coordinates), std::end(coordinates), [](const util::Coordinate coordinate) {
return !coordinate.IsValid();
});
return !std::any_of(std::begin(coordinates),
std::end(coordinates),
[](const util::Coordinate coordinate)
{ return !coordinate.IsValid(); });
}
bool CheckAlgorithms(const api::BaseParameters &params,
@@ -105,45 +105,45 @@ class BasePlugin
{
// are all phantoms from a tiny cc?
const auto all_in_same_tiny_component =
[](const std::vector<PhantomCandidateAlternatives> &alts_list) {
return std::any_of(
alts_list.front().first.begin(),
alts_list.front().first.end(),
// For each of the first possible phantoms, check if all other
// positions in the list have a phantom from the same small component.
[&](const PhantomNode &phantom) {
if (!phantom.component.is_tiny)
{
return false;
}
const auto component_id = phantom.component.id;
return std::all_of(
std::next(alts_list.begin()),
std::end(alts_list),
[component_id](const PhantomCandidateAlternatives &alternatives) {
return candidatesHaveComponent(alternatives.first, component_id);
});
});
};
[](const std::vector<PhantomCandidateAlternatives> &alts_list)
{
return std::any_of(
alts_list.front().first.begin(),
alts_list.front().first.end(),
// For each of the first possible phantoms, check if all other
// positions in the list have a phantom from the same small component.
[&](const PhantomNode &phantom)
{
if (!phantom.component.is_tiny)
{
return false;
}
const auto component_id = phantom.component.id;
return std::all_of(
std::next(alts_list.begin()),
std::end(alts_list),
[component_id](const PhantomCandidateAlternatives &alternatives)
{ return candidatesHaveComponent(alternatives.first, component_id); });
});
};
// Move the alternative into the final list
const auto fallback_to_big_component = [](PhantomCandidateAlternatives &alternatives) {
const auto fallback_to_big_component = [](PhantomCandidateAlternatives &alternatives)
{
auto no_big_alternative = alternatives.second.empty();
return no_big_alternative ? std::move(alternatives.first)
: std::move(alternatives.second);
};
// Move the alternative into the final list
const auto use_closed_phantom = [](PhantomCandidateAlternatives &alternatives) {
return std::move(alternatives.first);
};
const auto use_closed_phantom = [](PhantomCandidateAlternatives &alternatives)
{ return std::move(alternatives.first); };
const auto no_alternatives =
std::all_of(alternatives_list.begin(),
alternatives_list.end(),
[](const PhantomCandidateAlternatives &alternatives) {
return alternatives.second.empty();
});
[](const PhantomCandidateAlternatives &alternatives)
{ return alternatives.second.empty(); });
std::vector<PhantomNodeCandidates> snapped_phantoms;
snapped_phantoms.reserve(alternatives_list.size());
@@ -313,12 +313,12 @@ class BasePlugin
alternatives.end(),
coordinates.begin(),
coordinates.end(),
[](const auto &candidates_pair, const auto &coordinate) {
[](const auto &candidates_pair, const auto &coordinate)
{
return std::any_of(candidates_pair.first.begin(),
candidates_pair.first.end(),
[&](const auto &phantom) {
return phantom.input_location == coordinate;
});
[&](const auto &phantom)
{ return phantom.input_location == coordinate; });
});
std::size_t missing_index = std::distance(alternatives.begin(), mismatch.first);
return std::string("Could not find a matching segment for coordinate ") +
+2 -1
View File
@@ -39,7 +39,8 @@ std::string encodePolyline(CoordVectorForwardIter begin, CoordVectorForwardIter
begin,
end,
[&delta_numbers, &current_lat, &current_lon, coordinate_to_polyline](
const util::Coordinate loc) {
const util::Coordinate loc)
{
const int lat_diff =
std::round(static_cast<int>(loc.lat) * coordinate_to_polyline) - current_lat;
const int lon_diff =
@@ -71,24 +71,27 @@ void insertTargetInReverseHeap(Heap &reverse_heap, const PhantomNode &target)
static constexpr bool FORWARD_DIRECTION = true;
static constexpr bool REVERSE_DIRECTION = false;
// Identify nodes in the forward(reverse) search direction that will require loop forcing
// Identify nodes in the forward(reverse) search direction that will require step forcing
// e.g. if source and destination nodes are on the same segment.
std::vector<NodeID> getForwardLoopNodes(const PhantomEndpointCandidates &candidates);
std::vector<NodeID> getForwardLoopNodes(const PhantomCandidatesToTarget &candidates);
std::vector<NodeID> getBackwardLoopNodes(const PhantomEndpointCandidates &candidates);
std::vector<NodeID> getBackwardLoopNodes(const PhantomCandidatesToTarget &candidates);
std::vector<NodeID> getForwardForceNodes(const PhantomEndpointCandidates &candidates);
std::vector<NodeID> getForwardForceNodes(const PhantomCandidatesToTarget &candidates);
std::vector<NodeID> getBackwardForceNodes(const PhantomEndpointCandidates &candidates);
std::vector<NodeID> getBackwardForceNodes(const PhantomCandidatesToTarget &candidates);
// Find the specific phantom node endpoints for a given path from a list of candidates.
PhantomEndpoints endpointsFromCandidates(const PhantomEndpointCandidates &candidates,
const std::vector<NodeID> &path);
template <typename HeapNodeT>
inline bool force_loop(const std::vector<NodeID> &force_nodes, const HeapNodeT &heap_node)
inline bool shouldForceStep(const std::vector<NodeID> &force_nodes,
const HeapNodeT &forward_heap_node,
const HeapNodeT &reverse_heap_node)
{
// if loops are forced, they are so at the source
return !force_nodes.empty() &&
std::find(force_nodes.begin(), force_nodes.end(), heap_node.node) != force_nodes.end() &&
heap_node.data.parent == heap_node.node;
// routing steps are forced when the node is a source of both forward and reverse search heaps.
return forward_heap_node.data.parent == forward_heap_node.node &&
reverse_heap_node.data.parent == reverse_heap_node.node &&
std::find(force_nodes.begin(), force_nodes.end(), forward_heap_node.node) !=
force_nodes.end();
}
template <typename Heap>
@@ -190,8 +193,10 @@ void annotatePath(const FacadeT &facade,
std::vector<SegmentDuration> duration_vector;
std::vector<DatasourceID> datasource_vector;
const auto get_segment_geometry = [&](const auto geometry_index) {
const auto copy = [](auto &vector, const auto range) {
const auto get_segment_geometry = [&](const auto geometry_index)
{
const auto copy = [](auto &vector, const auto range)
{
vector.resize(range.size());
std::copy(range.begin(), range.end(), vector.begin());
};
@@ -112,8 +112,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
NodeID &middle_node_id,
EdgeWeight &upper_bound,
EdgeWeight min_edge_offset,
const std::vector<NodeID> &force_loop_forward_nodes,
const std::vector<NodeID> &force_loop_reverse_nodes)
const std::vector<NodeID> &force_step_nodes)
{
auto heapNode = forward_heap.DeleteMinGetHeapNode();
const auto reverseHeapNode = reverse_heap.GetHeapNodeIfWasInserted(heapNode.node);
@@ -123,13 +122,13 @@ void routingStep(const DataFacade<Algorithm> &facade,
const EdgeWeight new_weight = reverseHeapNode->weight + heapNode.weight;
if (new_weight < upper_bound)
{
if (force_loop(force_loop_forward_nodes, heapNode) ||
force_loop(force_loop_reverse_nodes, heapNode) ||
if (shouldForceStep(force_step_nodes, heapNode, reverseHeapNode.get()) ||
// in this case we are looking at a bi-directional way where the source
// and target phantom are on the same edge based node
new_weight < EdgeWeight{0})
{
// check whether there is a loop present at the node
// Before forcing step, check whether there is a loop present at the node.
// We may find a valid weight path by following the loop.
for (const auto edge : facade.GetAdjacentEdgeRange(heapNode.node))
{
const auto &data = facade.GetEdgeData(edge);
@@ -294,9 +293,9 @@ EdgeDistance calculateEBGNodeAnnotations(const DataFacade<Algorithm> &facade,
// Look for an edge on the forward CH graph (.forward)
EdgeID smaller_edge_id =
facade.FindSmallestEdge(std::get<0>(edge), std::get<1>(edge), [](const auto &data) {
return data.forward;
});
facade.FindSmallestEdge(std::get<0>(edge),
std::get<1>(edge),
[](const auto &data) { return data.forward; });
// If we didn't find one there, the we might be looking at a part of the path that
// was found using the backward search. Here, we flip the node order (.second,
@@ -381,7 +380,8 @@ void unpackPath(const FacadeT &facade,
unpackPath(facade,
packed_path_begin,
packed_path_end,
[&](std::pair<NodeID, NodeID> &edge, const auto &edge_id) {
[&](std::pair<NodeID, NodeID> &edge, const auto &edge_id)
{
BOOST_ASSERT(edge.first == unpacked_nodes.back());
unpacked_nodes.push_back(edge.second);
unpacked_edges.push_back(edge_id);
@@ -420,23 +420,22 @@ void retrievePackedPathFromSingleManyToManyHeap(
// assumes that heaps are already setup correctly.
// ATTENTION: This only works if no additional offset is supplied next to the Phantom Node
// Offsets.
// In case additional offsets are supplied, you might have to force a loop first.
// A forced loop might be necessary, if source and target are on the same segment.
// In case additional offsets are supplied, you might have to force a routing step first.
// A forced step might be necessary, if source and target are on the same segment.
// If this is the case and the offsets of the respective direction are larger for the source
// than the target
// then a force loop is required (e.g. source_phantom.forward_segment_id ==
// then a force step is required (e.g. source_phantom.forward_segment_id ==
// target_phantom.forward_segment_id
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
// requires
// a force loop, if the heaps have been initialized with positive offsets.
// a force step, if the heaps have been initialized with positive offsets.
void search(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
EdgeWeight &weight,
std::vector<NodeID> &packed_leg,
const std::vector<NodeID> &force_loop_forward_node,
const std::vector<NodeID> &force_loop_reverse_node,
const std::vector<NodeID> &force_step_nodes,
const EdgeWeight duration_upper_bound = INVALID_EDGE_WEIGHT);
template <typename PhantomEndpointT>
@@ -446,8 +445,7 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
EdgeWeight &weight,
std::vector<NodeID> &packed_leg,
const std::vector<NodeID> &force_loop_forward_node,
const std::vector<NodeID> &force_loop_reverse_node,
const std::vector<NodeID> &force_step_nodes,
const PhantomEndpointT & /*endpoints*/,
const EdgeWeight duration_upper_bound = INVALID_EDGE_WEIGHT)
{
@@ -458,14 +456,13 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
reverse_heap,
weight,
packed_leg,
force_loop_forward_node,
force_loop_reverse_node,
force_step_nodes,
duration_upper_bound);
}
// Requires the heaps for be empty
// If heaps should be adjusted to be initialized outside of this function,
// the addition of force_loop parameters might be required
// the addition of force_step parameters might be required
double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<ch::Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
@@ -30,7 +30,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
const PhantomNode &source,
const PhantomNode &target)
{
auto level = [&partition, node](const SegmentID &source, const SegmentID &target) {
auto level = [&partition, node](const SegmentID &source, const SegmentID &target)
{
if (source.enabled && target.enabled)
return partition.GetQueryLevel(source.id, target.id, node);
return INVALID_LEVEL_ID;
@@ -59,7 +60,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
endpoint_candidates.source_phantoms.begin(),
endpoint_candidates.source_phantoms.end(),
INVALID_LEVEL_ID,
[&](LevelID current_level, const PhantomNode &source) {
[&](LevelID current_level, const PhantomNode &source)
{
return std::min(
current_level,
getNodeQueryLevel(partition, node, source, endpoint_candidates.target_phantom));
@@ -76,7 +78,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
endpoint_candidates.source_phantoms.begin(),
endpoint_candidates.source_phantoms.end(),
INVALID_LEVEL_ID,
[&](LevelID level_1, const PhantomNode &source) {
[&](LevelID level_1, const PhantomNode &source)
{
return std::min(
level_1,
std::accumulate(endpoint_candidates.target_phantoms.begin(),
@@ -119,7 +122,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
const NodeID node,
const PhantomNodeCandidates &candidates)
{
auto highest_different_level = [&partition, node](const SegmentID &segment) {
auto highest_different_level = [&partition, node](const SegmentID &segment)
{
return segment.enabled ? partition.GetHighestDifferentLevel(segment.id, node)
: INVALID_LEVEL_ID;
};
@@ -128,7 +132,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
std::accumulate(candidates.begin(),
candidates.end(),
INVALID_LEVEL_ID,
[&](LevelID current_level, const PhantomNode &phantom_node) {
[&](LevelID current_level, const PhantomNode &phantom_node)
{
auto highest_level =
std::min(highest_different_level(phantom_node.forward_segment_id),
highest_different_level(phantom_node.reverse_segment_id));
@@ -151,9 +156,11 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
// This is equivalent to min_{∀ source, target} partition.GetQueryLevel(source, node, target)
auto init = getNodeQueryLevel(partition, node, candidates_list[phantom_index]);
auto result = std::accumulate(
phantom_indices.begin(), phantom_indices.end(), init, [&](LevelID level, size_t index) {
return std::min(level, getNodeQueryLevel(partition, node, candidates_list[index]));
});
phantom_indices.begin(),
phantom_indices.end(),
init,
[&](LevelID level, size_t index)
{ return std::min(level, getNodeQueryLevel(partition, node, candidates_list[index])); });
return result;
}
} // namespace
@@ -266,7 +273,7 @@ template <bool DIRECTION, typename Algorithm, typename... Args>
void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
const typename SearchEngineData<Algorithm>::QueryHeap::HeapNode &heapNode,
const Args &... args)
const Args &...args)
{
const auto &partition = facade.GetMultiLevelPartition();
const auto &cells = facade.GetCellStorage();
@@ -382,9 +389,8 @@ void routingStep(const DataFacade<Algorithm> &facade,
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
NodeID &middle_node,
EdgeWeight &path_upper_bound,
const std::vector<NodeID> &force_loop_forward_nodes,
const std::vector<NodeID> &force_loop_reverse_nodes,
const Args &... args)
const std::vector<NodeID> &force_step_nodes,
const Args &...args)
{
const auto heapNode = forward_heap.DeleteMinGetHeapNode();
const auto weight = heapNode.weight;
@@ -402,11 +408,8 @@ void routingStep(const DataFacade<Algorithm> &facade,
auto reverse_weight = reverseHeapNode->weight;
auto path_weight = weight + reverse_weight;
// MLD uses loops forcing only to prune single node paths in forward and/or
// backward direction (there is no need to force loops in MLD but in CH)
if (!force_loop(force_loop_forward_nodes, heapNode) &&
!force_loop(force_loop_reverse_nodes, heapNode) && (path_weight >= EdgeWeight{0}) &&
(path_weight < path_upper_bound))
if (!shouldForceStep(force_step_nodes, heapNode, reverseHeapNode.get()) &&
(path_weight >= EdgeWeight{0}) && (path_weight < path_upper_bound))
{
middle_node = heapNode.node;
path_upper_bound = path_weight;
@@ -431,10 +434,9 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
const DataFacade<Algorithm> &facade,
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const std::vector<NodeID> &force_loop_forward_nodes,
const std::vector<NodeID> &force_loop_reverse_nodes,
const std::vector<NodeID> &force_step_nodes,
EdgeWeight weight_upper_bound,
const Args &... args)
const Args &...args)
{
if (forward_heap.Empty() || reverse_heap.Empty())
{
@@ -456,27 +458,15 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
{
if (!forward_heap.Empty())
{
routingStep<FORWARD_DIRECTION>(facade,
forward_heap,
reverse_heap,
middle,
weight,
force_loop_forward_nodes,
force_loop_reverse_nodes,
args...);
routingStep<FORWARD_DIRECTION>(
facade, forward_heap, reverse_heap, middle, weight, force_step_nodes, args...);
if (!forward_heap.Empty())
forward_heap_min = forward_heap.MinKey();
}
if (!reverse_heap.Empty())
{
routingStep<REVERSE_DIRECTION>(facade,
reverse_heap,
forward_heap,
middle,
weight,
force_loop_reverse_nodes,
force_loop_forward_nodes,
args...);
routingStep<REVERSE_DIRECTION>(
facade, reverse_heap, forward_heap, middle, weight, force_step_nodes, args...);
if (!reverse_heap.Empty())
reverse_heap_min = reverse_heap.MinKey();
}
@@ -505,9 +495,7 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
for (auto const &packed_edge : packed_path)
{
NodeID source, target;
bool overlay_edge;
std::tie(source, target, overlay_edge) = packed_edge;
auto [source, target, overlay_edge] = packed_edge;
if (!overlay_edge)
{ // a base graph edge
unpacked_nodes.push_back(target);
@@ -527,21 +515,14 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
forward_heap.Insert(source, {0}, {source});
reverse_heap.Insert(target, {0}, {target});
// TODO: when structured bindings will be allowed change to
// auto [subpath_weight, subpath_source, subpath_target, subpath] = ...
EdgeWeight subpath_weight;
std::vector<NodeID> subpath_nodes;
std::vector<EdgeID> subpath_edges;
std::tie(subpath_weight, subpath_nodes, subpath_edges) =
search(engine_working_data,
facade,
forward_heap,
reverse_heap,
force_loop_forward_nodes,
force_loop_reverse_nodes,
INVALID_EDGE_WEIGHT,
sublevel,
parent_cell_id);
auto [subpath_weight, subpath_nodes, subpath_edges] = search(engine_working_data,
facade,
forward_heap,
reverse_heap,
force_step_nodes,
INVALID_EDGE_WEIGHT,
sublevel,
parent_cell_id);
BOOST_ASSERT(!subpath_edges.empty());
BOOST_ASSERT(subpath_nodes.size() > 1);
BOOST_ASSERT(subpath_nodes.front() == source);
@@ -563,8 +544,7 @@ inline void search(SearchEngineData<Algorithm> &engine_working_data,
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
EdgeWeight &weight,
std::vector<NodeID> &unpacked_nodes,
const std::vector<NodeID> &force_loop_forward_node,
const std::vector<NodeID> &force_loop_reverse_node,
const std::vector<NodeID> &force_step_nodes,
const PhantomEndpointT &endpoints,
const EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
{
@@ -573,8 +553,7 @@ inline void search(SearchEngineData<Algorithm> &engine_working_data,
facade,
forward_heap,
reverse_heap,
force_loop_forward_node,
force_loop_reverse_node,
force_step_nodes,
weight_upper_bound,
endpoints);
}
@@ -601,7 +580,8 @@ void unpackPath(const FacadeT &facade,
util::for_each_pair(
packed_path_begin,
packed_path_end,
[&facade, &unpacked_nodes, &unpacked_edges](const auto from, const auto to) {
[&facade, &unpacked_nodes, &unpacked_edges](const auto from, const auto to)
{
unpacked_nodes.push_back(to);
unpacked_edges.push_back(facade.FindEdge(from, to));
});
@@ -625,28 +605,46 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
const PhantomEndpoints endpoints{source_phantom, target_phantom};
insertNodesInHeaps(forward_heap, reverse_heap, endpoints);
EdgeWeight weight = INVALID_EDGE_WEIGHT;
std::vector<NodeID> unpacked_nodes;
std::vector<EdgeID> unpacked_edges;
std::tie(weight, unpacked_nodes, unpacked_edges) = search(engine_working_data,
facade,
forward_heap,
reverse_heap,
{},
{},
weight_upper_bound,
endpoints);
auto [weight, unpacked_nodes, unpacked_edges] = search(
engine_working_data, facade, forward_heap, reverse_heap, {}, weight_upper_bound, endpoints);
if (weight == INVALID_EDGE_WEIGHT)
{
return std::numeric_limits<double>::max();
}
std::vector<PathData> unpacked_path;
BOOST_ASSERT(unpacked_nodes.size() >= 1);
annotatePath(facade, endpoints, unpacked_nodes, unpacked_edges, unpacked_path);
EdgeDistance distance = {0.0};
return getPathDistance(facade, unpacked_path, source_phantom, target_phantom);
if (source_phantom.forward_segment_id.id == unpacked_nodes.front())
{
BOOST_ASSERT(source_phantom.forward_segment_id.enabled);
distance = EdgeDistance{0} - source_phantom.GetForwardDistance();
}
else if (source_phantom.reverse_segment_id.id == unpacked_nodes.front())
{
BOOST_ASSERT(source_phantom.reverse_segment_id.enabled);
distance = EdgeDistance{0} - source_phantom.GetReverseDistance();
}
for (size_t index = 0; index < unpacked_nodes.size() - 1; ++index)
{
distance += facade.GetNodeDistance(unpacked_nodes[index]);
}
if (target_phantom.forward_segment_id.id == unpacked_nodes.back())
{
BOOST_ASSERT(target_phantom.forward_segment_id.enabled);
distance += target_phantom.GetForwardDistance();
}
else if (target_phantom.reverse_segment_id.id == unpacked_nodes.back())
{
BOOST_ASSERT(target_phantom.reverse_segment_id.enabled);
distance += target_phantom.GetReverseDistance();
}
return from_alias<double>(distance);
}
} // namespace osrm::engine::routing_algorithms::mld
@@ -19,8 +19,7 @@ void searchWithUTurn(SearchEngineData<Algorithm> &engine_working_data,
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
typename SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const PhantomEndpointCandidates &candidates,
const EdgeWeight &total_weight,
EdgeWeight &new_total_weight,
EdgeWeight &leg_weight,
std::vector<NodeID> &leg_packed_path)
{
forward_heap.Clear();
@@ -31,14 +30,14 @@ void searchWithUTurn(SearchEngineData<Algorithm> &engine_working_data,
if (source.IsValidForwardSource())
{
forward_heap.Insert(source.forward_segment_id.id,
total_weight - source.GetForwardWeightPlusOffset(),
EdgeWeight{0} - source.GetForwardWeightPlusOffset(),
source.forward_segment_id.id);
}
if (source.IsValidReverseSource())
{
forward_heap.Insert(source.reverse_segment_id.id,
total_weight - source.GetReverseWeightPlusOffset(),
EdgeWeight{0} - source.GetReverseWeightPlusOffset(),
source.reverse_segment_id.id);
}
}
@@ -62,10 +61,9 @@ void searchWithUTurn(SearchEngineData<Algorithm> &engine_working_data,
facade,
forward_heap,
reverse_heap,
new_total_weight,
leg_weight,
leg_packed_path,
getForwardLoopNodes(candidates),
getBackwardLoopNodes(candidates),
{},
candidates);
}
@@ -125,8 +123,7 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
reverse_heap,
new_total_weight_to_forward,
leg_packed_path_forward,
getForwardLoopNodes(candidates),
{},
getForwardForceNodes(candidates),
candidates);
}
@@ -165,8 +162,7 @@ void search(SearchEngineData<Algorithm> &engine_working_data,
reverse_heap,
new_total_weight_to_reverse,
leg_packed_path_reverse,
{},
getBackwardLoopNodes(candidates),
getBackwardForceNodes(candidates),
candidates);
}
}
@@ -248,7 +244,8 @@ constructRouteResult(const DataFacade<Algorithm> &facade,
auto source_it =
std::find_if(source_candidates.begin(),
source_candidates.end(),
[&start_node](const auto &source_phantom) {
[&start_node](const auto &source_phantom)
{
return (start_node == source_phantom.forward_segment_id.id ||
start_node == source_phantom.reverse_segment_id.id);
});
@@ -257,7 +254,8 @@ constructRouteResult(const DataFacade<Algorithm> &facade,
auto target_it =
std::find_if(target_candidates.begin(),
target_candidates.end(),
[&end_node](const auto &target_phantom) {
[&end_node](const auto &target_phantom)
{
return (end_node == target_phantom.forward_segment_id.id ||
end_node == target_phantom.reverse_segment_id.id);
});
@@ -302,7 +300,7 @@ shortestPathWithWaypointUTurns(SearchEngineData<Algorithm> &engine_working_data,
PhantomEndpointCandidates search_candidates{waypoint_candidates[i],
waypoint_candidates[i + 1]};
std::vector<NodeID> packed_leg;
EdgeWeight new_total_weight = INVALID_EDGE_WEIGHT;
EdgeWeight leg_weight = INVALID_EDGE_WEIGHT;
// We have a valid path up to this leg
BOOST_ASSERT(total_weight != INVALID_EDGE_WEIGHT);
@@ -311,16 +309,15 @@ shortestPathWithWaypointUTurns(SearchEngineData<Algorithm> &engine_working_data,
forward_heap,
reverse_heap,
search_candidates,
total_weight,
new_total_weight,
leg_weight,
packed_leg);
if (new_total_weight == INVALID_EDGE_WEIGHT)
if (leg_weight == INVALID_EDGE_WEIGHT)
return {};
packed_leg_begin.push_back(total_packed_path.size());
total_packed_path.insert(total_packed_path.end(), packed_leg.begin(), packed_leg.end());
total_weight = new_total_weight;
total_weight += leg_weight;
};
// Add sentinel
@@ -466,16 +463,16 @@ struct route_state
last.total_weight_to_forward.resize(init_candidates.size(), {0});
last.total_weight_to_reverse.resize(init_candidates.size(), {0});
// Initialize routability from source validity.
std::transform(
init_candidates.begin(),
init_candidates.end(),
std::back_inserter(last.reached_forward_node_target),
[](const PhantomNode &phantom_node) { return phantom_node.IsValidForwardSource(); });
std::transform(
init_candidates.begin(),
init_candidates.end(),
std::back_inserter(last.reached_reverse_node_target),
[](const PhantomNode &phantom_node) { return phantom_node.IsValidReverseSource(); });
std::transform(init_candidates.begin(),
init_candidates.end(),
std::back_inserter(last.reached_forward_node_target),
[](const PhantomNode &phantom_node)
{ return phantom_node.IsValidForwardSource(); });
std::transform(init_candidates.begin(),
init_candidates.end(),
std::back_inserter(last.reached_reverse_node_target),
[](const PhantomNode &phantom_node)
{ return phantom_node.IsValidReverseSource(); });
}
bool completeLeg()
@@ -613,15 +610,21 @@ struct route_state
{
// Find the segment from final leg with the shortest path
auto forward_range = util::irange<std::size_t>(0UL, last.total_weight_to_forward.size());
auto forward_min =
std::min_element(forward_range.begin(), forward_range.end(), [&](size_t a, size_t b) {
auto forward_min = std::min_element(
forward_range.begin(),
forward_range.end(),
[&](size_t a, size_t b)
{
return (last.total_weight_to_forward[a] < last.total_weight_to_forward[b] ||
(last.total_weight_to_forward[a] == last.total_weight_to_forward[b] &&
last.total_nodes_to_forward[a] < last.total_nodes_to_forward[b]));
});
auto reverse_range = util::irange<std::size_t>(0UL, last.total_weight_to_reverse.size());
auto reverse_min =
std::min_element(reverse_range.begin(), reverse_range.end(), [&](size_t a, size_t b) {
auto reverse_min = std::min_element(
reverse_range.begin(),
reverse_range.end(),
[&](size_t a, size_t b)
{
return (last.total_weight_to_reverse[a] < last.total_weight_to_reverse[b] ||
(last.total_weight_to_reverse[a] == last.total_weight_to_reverse[b] &&
last.total_nodes_to_reverse[a] < last.total_nodes_to_reverse[b]));
+3 -3
View File
@@ -27,9 +27,9 @@ inline auto getClassData(const std::size_t index)
inline bool isValidClassName(const std::string &name)
{
return std::find_if_not(name.begin(), name.end(), [](const auto c) {
return std::isalnum(c);
}) == name.end();
return std::find_if_not(name.begin(),
name.end(),
[](const auto c) { return std::isalnum(c); }) == name.end();
}
} // namespace osrm::extractor
@@ -125,9 +125,8 @@ inline std::string canonicalizeStringList(std::string strlist, const std::string
// collapse spaces; this is needed in case we expand "; X" => "; X" above
// but also makes sense to do irregardless of the fact - canonicalizing strings.
const auto spaces = [](unsigned char lhs, unsigned char rhs) {
return ::isspace(lhs) && ::isspace(rhs);
};
const auto spaces = [](unsigned char lhs, unsigned char rhs)
{ return ::isspace(lhs) && ::isspace(rhs); };
auto it = std::unique(begin(strlist), end(strlist), spaces);
strlist.erase(it, end(strlist));
+4 -2
View File
@@ -133,7 +133,8 @@ class ExtractionRelationContainer
(void)res; // prevent unused warning in release
}
auto MergeRefMap = [&](RelationRefMap &source, RelationRefMap &target) {
auto MergeRefMap = [&](RelationRefMap &source, RelationRefMap &target)
{
for (auto it : source)
{
auto &v = target[it.first];
@@ -151,7 +152,8 @@ class ExtractionRelationContainer
const RelationIDList &GetRelations(const OsmIDTyped &member_id) const
{
auto getFromMap = [this](std::uint64_t id,
const RelationRefMap &map) -> const RelationIDList & {
const RelationRefMap &map) -> const RelationIDList &
{
auto it = map.find(id);
if (it != map.end())
return it->second;
+2 -1
View File
@@ -453,7 +453,8 @@ void readRawNBGraph(const boost::filesystem::path &path,
coordinates.resize(number_of_nodes);
osm_node_ids.reserve(number_of_nodes);
auto index = 0;
auto decode = [&](const auto &current_node) {
auto decode = [&](const auto &current_node)
{
coordinates[index].lon = current_node.lon;
coordinates[index].lat = current_node.lat;
osm_node_ids.push_back(current_node.node_id);
@@ -26,16 +26,14 @@ namespace osrm::extractor::intersection
inline auto makeCompareAngularDeviation(const double angle)
{
return [angle](const auto &lhs, const auto &rhs) {
return util::angularDeviation(lhs.angle, angle) < util::angularDeviation(rhs.angle, angle);
};
return [angle](const auto &lhs, const auto &rhs)
{ return util::angularDeviation(lhs.angle, angle) < util::angularDeviation(rhs.angle, angle); };
}
inline auto makeExtractLanesForRoad(const util::NodeBasedDynamicGraph &node_based_graph)
{
return [&node_based_graph](const auto &road) {
return node_based_graph.GetEdgeData(road.eid).road_classification.GetNumberOfLanes();
};
return [&node_based_graph](const auto &road)
{ return node_based_graph.GetEdgeData(road.eid).road_classification.GetNumberOfLanes(); };
}
// When viewing an intersection from an incoming edge, we can transform a shape into a view which
@@ -63,7 +61,10 @@ template <typename Self> struct EnableShapeOps
auto FindClosestBearing(double base_bearing) const
{
return std::min_element(
self()->begin(), self()->end(), [base_bearing](const auto &lhs, const auto &rhs) {
self()->begin(),
self()->end(),
[base_bearing](const auto &lhs, const auto &rhs)
{
return util::angularDeviation(lhs.perceived_bearing, base_bearing) <
util::angularDeviation(rhs.perceived_bearing, base_bearing);
});
@@ -81,7 +82,8 @@ template <typename Self> struct EnableShapeOps
BOOST_ASSERT(!self()->empty());
auto initial = converter(self()->front());
const auto extract_maximal_value = [&initial, converter](const auto &road) {
const auto extract_maximal_value = [&initial, converter](const auto &road)
{
initial = std::max(initial, converter(road));
return false;
};
@@ -191,8 +193,10 @@ template <typename Self> struct EnableIntersectionOps
auto findClosestTurn(const double angle, const UnaryPredicate filter) const
{
BOOST_ASSERT(!self()->empty());
const auto candidate =
boost::range::min_element(*self(), [angle, &filter](const auto &lhs, const auto &rhs) {
const auto candidate = boost::range::min_element(
*self(),
[angle, &filter](const auto &lhs, const auto &rhs)
{
const auto filtered_lhs = filter(lhs), filtered_rhs = filter(rhs);
const auto deviation_lhs = util::angularDeviation(lhs.angle, angle),
deviation_rhs = util::angularDeviation(rhs.angle, angle);
+2 -3
View File
@@ -32,9 +32,8 @@ template <typename RestrictionFilter> class NodeRestrictionMap
// Find all restrictions applicable to (from,via,to) turns
auto Restrictions(NodeID from, NodeID via, NodeID to) const
{
const auto turnFilter = [this, to](const auto &restriction) {
return index_filter(restriction) && restriction->IsTurnRestricted(to);
};
const auto turnFilter = [this, to](const auto &restriction)
{ return index_filter(restriction) && restriction->IsTurnRestricted(to); };
return getRange(from, via) | boost::adaptors::filtered(turnFilter);
};
+16 -10
View File
@@ -187,11 +187,11 @@ IntersectionHandler::IsDistinctNarrowTurn(const EdgeID via_edge,
node_data_container.GetAnnotation(candidate_data.annotation_data);
auto const candidate_deviation = util::angularDeviation(candidate->angle, STRAIGHT_ANGLE);
auto const num_lanes = [](auto const &data) {
return data.flags.road_classification.GetNumberOfLanes();
};
auto const num_lanes = [](auto const &data)
{ return data.flags.road_classification.GetNumberOfLanes(); };
auto const lanes_number_equal = [&](auto const &compare_data) {
auto const lanes_number_equal = [&](auto const &compare_data)
{
// Check if the lanes number is the same going from the inbound edge to the compare road
return num_lanes(compare_data) > 0 && num_lanes(compare_data) == num_lanes(via_edge_data);
};
@@ -210,7 +210,8 @@ IntersectionHandler::IsDistinctNarrowTurn(const EdgeID via_edge,
// check if there are other narrow turns are not considered passing a low category or simply
// a link of the same type as the potentially obvious turn
auto const is_similar_turn = [&](auto const &road) {
auto const is_similar_turn = [&](auto const &road)
{
// 1. Skip the candidate road
if (road.eid == candidate->eid)
{
@@ -405,7 +406,8 @@ IntersectionHandler::IsDistinctWideTurn(const EdgeID via_edge,
// Deviation is larger than NARROW_TURN_ANGLE0 here for the candidate
// check if there is any turn, that might look just as obvious, even though it might not
// be allowed. Entry-allowed isn't considered a valid distinction criterion here
auto const is_similar_turn = [&](auto const &road) {
auto const is_similar_turn = [&](auto const &road)
{
// 1. Skip over our candidate
if (road.eid == candidate->eid)
return false;
@@ -503,7 +505,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
node_data_container.GetAnnotation(via_edge_data.annotation_data);
// implement a filter, taking out all roads of lower class or different names
auto const continues_on_name_with_higher_class = [&](auto const &road) {
auto const continues_on_name_with_higher_class = [&](auto const &road)
{
// it needs to be possible to enter the road
if (!road.entry_allowed)
return true;
@@ -550,7 +553,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
// this check is not part of the main conditions, so that if the turn looks obvious from all
// other perspectives, a mode change will not result in different classification
auto const to_index_if_valid = [&](auto const iterator) -> std::size_t {
auto const to_index_if_valid = [&](auto const iterator) -> std::size_t
{
auto const &from_data = node_based_graph.GetEdgeData(via_edge);
auto const &to_data = node_based_graph.GetEdgeData(iterator->eid);
@@ -577,7 +581,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
// opposed to before, we do not care about name changes, again: this is a filter, so internal
// false/true will be negated for selection
auto const valid_of_higher_or_same_category = [&](auto const &road) {
auto const valid_of_higher_or_same_category = [&](auto const &road)
{
if (!road.entry_allowed)
return true;
@@ -640,7 +645,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
const auto all_roads_have_same_name =
std::all_of(intersection.begin(),
intersection.end(),
[id = via_edge_annotation.name_id, this](auto const &road) {
[id = via_edge_annotation.name_id, this](auto const &road)
{
auto const data_id = node_based_graph.GetEdgeData(road.eid).annotation_data;
auto const name_id = node_data_container.GetAnnotation(data_id).name_id;
return (name_id != EMPTY_NAMEID) && (name_id == id);
+1 -1
View File
@@ -71,7 +71,7 @@ trimLaneString(std::string lane_string, std::int32_t count_left, std::int32_t co
OSRM_ATTR_WARN_UNUSED
inline std::string applyAccessTokens(std::string lane_string, const std::string &access_tokens)
{
typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
using tokenizer = boost::tokenizer<boost::char_separator<char>>;
boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
tokenizer tokens(lane_string, sep);
tokenizer access(access_tokens, sep);
+20 -20
View File
@@ -1,13 +1,14 @@
#ifndef OSRM_GUIDANCE_TURN_INSTRUCTION_HPP_
#define OSRM_GUIDANCE_TURN_INSTRUCTION_HPP_
#include <algorithm>
#include <cstdint>
#include "guidance/roundabout_type.hpp"
#include "util/attributes.hpp"
#include "util/typedefs.hpp"
#include <algorithm>
#include <array>
#include <cstdint>
namespace osrm::guidance
{
@@ -154,24 +155,23 @@ inline bool operator==(const TurnInstruction lhs, const TurnInstruction rhs)
inline bool hasRoundaboutType(const TurnInstruction instruction)
{
using namespace guidance::TurnType;
const constexpr TurnType::Enum valid_types[] = {TurnType::EnterRoundabout,
TurnType::EnterAndExitRoundabout,
TurnType::EnterRotary,
TurnType::EnterAndExitRotary,
TurnType::EnterRoundaboutIntersection,
TurnType::EnterAndExitRoundaboutIntersection,
TurnType::EnterRoundaboutAtExit,
TurnType::ExitRoundabout,
TurnType::EnterRotaryAtExit,
TurnType::ExitRotary,
TurnType::EnterRoundaboutIntersectionAtExit,
TurnType::ExitRoundaboutIntersection,
TurnType::StayOnRoundabout};
const constexpr std::array<TurnType::Enum, 13> valid_types = {
TurnType::EnterRoundabout,
TurnType::EnterAndExitRoundabout,
TurnType::EnterRotary,
TurnType::EnterAndExitRotary,
TurnType::EnterRoundaboutIntersection,
TurnType::EnterAndExitRoundaboutIntersection,
TurnType::EnterRoundaboutAtExit,
TurnType::ExitRoundabout,
TurnType::EnterRotaryAtExit,
TurnType::ExitRotary,
TurnType::EnterRoundaboutIntersectionAtExit,
TurnType::ExitRoundaboutIntersection,
TurnType::StayOnRoundabout};
const auto *first = valid_types;
const auto *last = first + sizeof(valid_types) / sizeof(valid_types[0]);
return std::find(first, last, instruction.type) != last;
return std::find(valid_types.cbegin(), valid_types.cend(), instruction.type) !=
valid_types.cend();
}
inline bool entersRoundabout(const guidance::TurnInstruction instruction)
+11 -8
View File
@@ -65,8 +65,8 @@ inline BisectionGraph makeBisectionGraph(const std::vector<util::Coordinate> &co
result_edges.reserve(edges.size());
// find the end of edges that belong to node_id
const auto advance_edge_itr = [&edges, &result_edges](const std::size_t node_id,
auto edge_itr) {
const auto advance_edge_itr = [&edges, &result_edges](const std::size_t node_id, auto edge_itr)
{
while (edge_itr != edges.end() && edge_itr->source == node_id)
{
result_edges.push_back(edge_itr->Reduce());
@@ -76,9 +76,9 @@ inline BisectionGraph makeBisectionGraph(const std::vector<util::Coordinate> &co
};
// create a bisection node, requires the ID of the node as well as the lower bound to its edges
const auto make_bisection_node = [&edges, &coordinates](const std::size_t node_id,
const auto begin_itr,
const auto end_itr) {
const auto make_bisection_node =
[&edges, &coordinates](const std::size_t node_id, const auto begin_itr, const auto end_itr)
{
std::size_t range_begin = std::distance(edges.begin(), begin_itr);
std::size_t range_end = std::distance(edges.begin(), end_itr);
return BisectionGraph::NodeT(range_begin, range_end, coordinates[node_id], node_id);
@@ -102,9 +102,12 @@ std::vector<BisectionInputEdge> adaptToBisectionEdge(std::vector<InputEdge> edge
std::vector<BisectionInputEdge> result;
result.reserve(edges.size());
std::transform(begin(edges), end(edges), std::back_inserter(result), [](const auto &edge) {
return BisectionInputEdge{edge.source, edge.target};
});
std::transform(begin(edges),
end(edges),
std::back_inserter(result),
[](const auto &edge) {
return BisectionInputEdge{edge.source, edge.target};
});
return result;
}
+6 -3
View File
@@ -298,7 +298,8 @@ template <storage::Ownership Ownership> class CellStorageImpl
auto set_num_nodes_fn,
auto set_boundary_offset_fn,
auto begin,
auto end) {
auto end)
{
BOOST_ASSERT(std::distance(begin, end) > 0);
const auto cell_id = begin->first;
@@ -316,7 +317,8 @@ template <storage::Ownership Ownership> class CellStorageImpl
util::for_each_range(
level_source_boundary.begin(),
level_source_boundary.end(),
[this, insert_cell_boundary](auto begin, auto end) {
[this, insert_cell_boundary](auto begin, auto end)
{
insert_cell_boundary(
source_boundary,
[](auto &cell, auto value) { cell.num_source_nodes = value; },
@@ -327,7 +329,8 @@ template <storage::Ownership Ownership> class CellStorageImpl
util::for_each_range(
level_destination_boundary.begin(),
level_destination_boundary.end(),
[this, insert_cell_boundary](auto begin, auto end) {
[this, insert_cell_boundary](auto begin, auto end)
{
insert_cell_boundary(
destination_boundary,
[](auto &cell, auto value) { cell.num_destination_nodes = value; },
+32 -24
View File
@@ -64,10 +64,13 @@ std::vector<OutputEdgeT> prepareEdgesForUsageInGraph(std::vector<extractor::Edge
// sort into blocks of edges with same source + target
// the we partition by the forward flag to sort all edges with a forward direction first.
// the we sort by weight to ensure the first forward edge is the smallest forward edge
std::sort(begin(edges), end(edges), [](const auto &lhs, const auto &rhs) {
return std::tie(lhs.source, lhs.target, rhs.data.forward, lhs.data.weight) <
std::tie(rhs.source, rhs.target, lhs.data.forward, rhs.data.weight);
});
std::sort(begin(edges),
end(edges),
[](const auto &lhs, const auto &rhs)
{
return std::tie(lhs.source, lhs.target, rhs.data.forward, lhs.data.weight) <
std::tie(rhs.source, rhs.target, lhs.data.forward, rhs.data.weight);
});
std::vector<OutputEdgeT> output_edges;
output_edges.reserve(edges.size());
@@ -77,10 +80,11 @@ std::vector<OutputEdgeT> prepareEdgesForUsageInGraph(std::vector<extractor::Edge
const NodeID source = begin_interval->source;
const NodeID target = begin_interval->target;
auto end_interval =
std::find_if_not(begin_interval, edges.end(), [source, target](const auto &edge) {
return std::tie(edge.source, edge.target) == std::tie(source, target);
});
auto end_interval = std::find_if_not(
begin_interval,
edges.end(),
[source, target](const auto &edge)
{ return std::tie(edge.source, edge.target) == std::tie(source, target); });
BOOST_ASSERT(begin_interval != end_interval);
// remove eigenloops
@@ -144,7 +148,8 @@ graphToEdges(const DynamicEdgeBasedGraph &edge_based_graph)
auto max_turn_id = tbb::parallel_reduce(
range,
NodeID{0},
[&edge_based_graph](const auto range, NodeID initial) {
[&edge_based_graph](const auto range, NodeID initial)
{
NodeID max_turn_id = initial;
for (auto node = range.begin(); node < range.end(); ++node)
{
@@ -159,26 +164,29 @@ graphToEdges(const DynamicEdgeBasedGraph &edge_based_graph)
[](const NodeID lhs, const NodeID rhs) { return std::max(lhs, rhs); });
std::vector<extractor::EdgeBasedEdge> edges(max_turn_id + 1);
tbb::parallel_for(range, [&](const auto range) {
for (auto node = range.begin(); node < range.end(); ++node)
tbb::parallel_for(
range,
[&](const auto range)
{
for (auto edge : edge_based_graph.GetAdjacentEdgeRange(node))
for (auto node = range.begin(); node < range.end(); ++node)
{
const auto &data = edge_based_graph.GetEdgeData(edge);
// we only need to save the forward edges, since the read method will
// convert from forward to bi-directional edges again
if (data.forward)
for (auto edge : edge_based_graph.GetAdjacentEdgeRange(node))
{
auto target = edge_based_graph.GetTarget(edge);
BOOST_ASSERT(data.turn_id <= max_turn_id);
edges[data.turn_id] = extractor::EdgeBasedEdge{node, target, data};
// only save the forward edge
edges[data.turn_id].data.forward = true;
edges[data.turn_id].data.backward = false;
const auto &data = edge_based_graph.GetEdgeData(edge);
// we only need to save the forward edges, since the read method will
// convert from forward to bi-directional edges again
if (data.forward)
{
auto target = edge_based_graph.GetTarget(edge);
BOOST_ASSERT(data.turn_id <= max_turn_id);
edges[data.turn_id] = extractor::EdgeBasedEdge{node, target, data};
// only save the forward edge
edges[data.turn_id].data.forward = true;
edges[data.turn_id].data.backward = false;
}
}
}
}
});
});
return edges;
}
+13 -10
View File
@@ -159,10 +159,11 @@ class MultiLevelGraph : public util::StaticGraph<EdgeDataT, Ownership>
auto GetHighestBorderLevel(const MultiLevelPartition &mlp, const ContainerT &edges) const
{
std::vector<LevelID> highest_border_level(edges.size());
std::transform(
edges.begin(), edges.end(), highest_border_level.begin(), [&mlp](const auto &edge) {
return mlp.GetHighestDifferentLevel(edge.source, edge.target);
});
std::transform(edges.begin(),
edges.end(),
highest_border_level.begin(),
[&mlp](const auto &edge)
{ return mlp.GetHighestDifferentLevel(edge.source, edge.target); });
return highest_border_level;
}
@@ -175,7 +176,8 @@ class MultiLevelGraph : public util::StaticGraph<EdgeDataT, Ownership>
tbb::parallel_sort(
permutation.begin(),
permutation.end(),
[&edges, &highest_border_level](const auto &lhs, const auto &rhs) {
[&edges, &highest_border_level](const auto &lhs, const auto &rhs)
{
// sort by source node and then by level in ascending order
return std::tie(edges[lhs].source, highest_border_level[lhs], edges[lhs].target) <
std::tie(edges[rhs].source, highest_border_level[rhs], edges[rhs].target);
@@ -201,11 +203,12 @@ class MultiLevelGraph : public util::StaticGraph<EdgeDataT, Ownership>
auto level_begin = iter;
for (auto level : util::irange<LevelID>(0, mlp.GetNumberOfLevels()))
{
iter = std::find_if(
iter, edge_and_level_end, [node, level](const auto &edge_and_level) {
return boost::get<0>(edge_and_level).source != node ||
boost::get<1>(edge_and_level) != level;
});
iter = std::find_if(iter,
edge_and_level_end,
[node, level](const auto &edge_and_level) {
return boost::get<0>(edge_and_level).source != node ||
boost::get<1>(edge_and_level) != level;
});
EdgeOffset offset = std::distance(level_begin, iter);
node_to_edge_offset.push_back(offset);
}
@@ -207,7 +207,8 @@ template <storage::Ownership Ownership> class MultiLevelPartitionImpl final
auto lidx = 0UL;
util::for_each_pair(level_offsets.begin(),
level_offsets.begin() + num_level,
[&](const auto offset, const auto next_offset) {
[&](const auto offset, const auto next_offset)
{
// create mask that has `bits` ones at its LSBs.
// 000011
BOOST_ASSERT(offset <= NUM_PARTITION_BITS);
@@ -274,9 +275,8 @@ template <storage::Ownership Ownership> class MultiLevelPartitionImpl final
{
std::stable_sort(permutation.begin(),
permutation.end(),
[&partition](const auto lhs, const auto rhs) {
return partition[lhs] < partition[rhs];
});
[&partition](const auto lhs, const auto rhs)
{ return partition[lhs] < partition[rhs]; });
}
// top down assign new cell ids
+2 -2
View File
@@ -21,7 +21,7 @@ template <typename Base> class NodeEntryWrapper : public Base
{
public:
template <typename... Args>
NodeEntryWrapper(std::size_t edges_begin_, std::size_t edges_end_, Args &&... args)
NodeEntryWrapper(std::size_t edges_begin_, std::size_t edges_end_, Args &&...args)
: Base(std::forward<Args>(args)...), edges_begin(edges_begin_), edges_end(edges_end_)
{
}
@@ -41,7 +41,7 @@ template <typename Base> class GraphConstructionWrapper : public Base
{
public:
template <typename... Args>
GraphConstructionWrapper(const NodeID source_, Args &&... args)
GraphConstructionWrapper(const NodeID source_, Args &&...args)
: Base(std::forward<Args>(args)...), source(source_)
{
}
+13 -9
View File
@@ -59,11 +59,13 @@ std::size_t removeUnconnectedBoundaryNodes(const GraphT &edge_based_graph,
if (level_index < static_cast<int>(partitions.size() - 1))
{
auto new_end = std::remove_if(
witnesses.begin(), witnesses.end(), [&](const auto &witness) {
return partitions[level_index + 1][node] !=
partitions[level_index + 1][witness.id];
});
auto new_end =
std::remove_if(witnesses.begin(),
witnesses.end(),
[&](const auto &witness) {
return partitions[level_index + 1][node] !=
partitions[level_index + 1][witness.id];
});
witnesses.resize(new_end - witnesses.begin());
}
if (witnesses.size() == 0)
@@ -87,10 +89,12 @@ std::size_t removeUnconnectedBoundaryNodes(const GraphT &edge_based_graph,
}
}
auto best_witness = std::min_element(
witnesses.begin(), witnesses.end(), [](const auto &lhs, const auto &rhs) {
return lhs.induced_border_edges < rhs.induced_border_edges;
});
auto best_witness =
std::min_element(witnesses.begin(),
witnesses.end(),
[](const auto &lhs, const auto &rhs) {
return lhs.induced_border_edges < rhs.induced_border_edges;
});
BOOST_ASSERT(best_witness != witnesses.end());
// assign `node` to same subcells as `best_witness`
+4 -4
View File
@@ -30,10 +30,10 @@ void reorderFirstLast(RandomIt first, RandomIt last, std::size_t n, Comparator c
// requirements.
std::reverse_iterator<RandomIt> rfirst{last}, rlast{first + n};
const auto flipped = [](auto fn) {
return [fn](auto &&lhs, auto &&rhs) {
return fn(std::forward<decltype(lhs)>(rhs), std::forward<decltype(rhs)>(lhs));
};
const auto flipped = [](auto fn)
{
return [fn](auto &&lhs, auto &&rhs)
{ return fn(std::forward<decltype(lhs)>(rhs), std::forward<decltype(rhs)>(lhs)); };
};
std::nth_element(rfirst, rfirst + (n - 1), rlast, flipped(comp));
+26 -26
View File
@@ -74,16 +74,16 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
: BaseParametersGrammar::base_type(root_rule)
{
const auto add_hint = [](engine::api::BaseParameters &base_parameters,
const std::vector<std::string> &hint_strings) {
const std::vector<std::string> &hint_strings)
{
if (!hint_strings.empty())
{
std::vector<engine::SegmentHint> location_hints(hint_strings.size());
std::transform(hint_strings.begin(),
hint_strings.end(),
location_hints.begin(),
[](const auto &hint_string) {
return engine::SegmentHint::FromBase64(hint_string);
});
[](const auto &hint_string)
{ return engine::SegmentHint::FromBase64(hint_string); });
base_parameters.hints.push_back(engine::Hint{std::move(location_hints)});
}
else
@@ -94,15 +94,16 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
const auto add_bearing =
[](engine::api::BaseParameters &base_parameters,
boost::optional<boost::fusion::vector2<short, short>> bearing_range) {
boost::optional<engine::Bearing> bearing;
if (bearing_range)
{
bearing = engine::Bearing{boost::fusion::at_c<0>(*bearing_range),
boost::fusion::at_c<1>(*bearing_range)};
}
base_parameters.bearings.push_back(std::move(bearing));
};
boost::optional<boost::fusion::vector2<short, short>> bearing_range)
{
boost::optional<engine::Bearing> bearing;
if (bearing_range)
{
bearing = engine::Bearing{boost::fusion::at_c<0>(*bearing_range),
boost::fusion::at_c<1>(*bearing_range)};
}
base_parameters.bearings.push_back(std::move(bearing));
};
polyline_chars = qi::char_("a-zA-Z0-9_.--[]{}@?|\\%~`^");
base64_char = qi::char_("a-zA-Z0-9--_=");
@@ -118,7 +119,8 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
location_rule = (double_ > qi::lit(',') >
double_)[qi::_val = ph::bind(
[](double lon, double lat) {
[](double lon, double lat)
{
return util::Coordinate(
util::toFixed(util::UnsafeFloatLongitude{lon}),
util::toFixed(util::UnsafeFloatLatitude{lat}));
@@ -126,19 +128,17 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
qi::_1,
qi::_2)];
polyline_rule = qi::as_string[qi::lit("polyline(") > +polyline_chars > ')']
[qi::_val = ph::bind(
[](const std::string &polyline) {
return engine::decodePolyline(polyline);
},
qi::_1)];
polyline_rule =
qi::as_string[qi::lit("polyline(") > +polyline_chars > ')']
[qi::_val = ph::bind([](const std::string &polyline)
{ return engine::decodePolyline(polyline); },
qi::_1)];
polyline6_rule = qi::as_string[qi::lit("polyline6(") > +polyline_chars > ')']
[qi::_val = ph::bind(
[](const std::string &polyline) {
return engine::decodePolyline<1000000>(polyline);
},
qi::_1)];
polyline6_rule =
qi::as_string[qi::lit("polyline6(") > +polyline_chars > ')']
[qi::_val = ph::bind([](const std::string &polyline)
{ return engine::decodePolyline<1000000>(polyline); },
qi::_1)];
query_rule =
((location_rule % ';') | polyline_rule |
@@ -54,8 +54,9 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
#endif
using AnnotationsType = engine::api::RouteParameters::AnnotationsType;
const auto add_annotation = [](engine::api::RouteParameters &route_parameters,
AnnotationsType route_param) {
const auto add_annotation =
[](engine::api::RouteParameters &route_parameters, AnnotationsType route_param)
{
route_parameters.annotations_type = route_parameters.annotations_type | route_param;
route_parameters.annotations =
route_parameters.annotations_type != AnnotationsType::None;
-12
View File
@@ -14,18 +14,6 @@
#include <memory>
#include <vector>
// workaround for incomplete std::shared_ptr compatibility in old boost versions
#if BOOST_VERSION < 105300 || defined BOOST_NO_CXX11_SMART_PTR
namespace boost
{
template <class T> const T *get_pointer(std::shared_ptr<T> const &p) { return p.get(); }
template <class T> T *get_pointer(std::shared_ptr<T> &p) { return p.get(); }
} // namespace boost
#endif
namespace osrm::server
{
+4 -2
View File
@@ -66,7 +66,8 @@ void readBoolVector(tar::FileReader &reader, const std::string &name, VectorT &d
using BlockType = std::uint64_t;
constexpr std::uint64_t BLOCK_BITS = CHAR_BIT * sizeof(BlockType);
const auto decode = [&](const BlockType block) {
const auto decode = [&](const BlockType block)
{
auto read_size = std::min<std::size_t>(count - index, BLOCK_BITS);
unpackBits<VectorT, BlockType>(data, index, read_size, block);
index += BLOCK_BITS;
@@ -87,7 +88,8 @@ void writeBoolVector(tar::FileWriter &writer, const std::string &name, const Vec
// FIXME on old boost version the function_input_iterator does not work with lambdas
// so we need to wrap it in a function here.
const std::function<BlockType()> encode_function = [&]() -> BlockType {
const std::function<BlockType()> encode_function = [&]() -> BlockType
{
auto write_size = std::min<std::size_t>(count - index, BLOCK_BITS);
auto packed = packBits<VectorT, BlockType>(data, index, write_size);
index += BLOCK_BITS;
+4 -4
View File
@@ -28,10 +28,10 @@ class SharedDataIndex
// Build mapping from block name to region
for (auto index : util::irange<std::uint32_t>(0, regions.size()))
{
regions[index].layout->List("",
boost::make_function_output_iterator([&](const auto &name) {
block_to_region[name] = index;
}));
regions[index].layout->List(
"",
boost::make_function_output_iterator([&](const auto &name)
{ block_to_region[name] = index; }));
}
}
+6 -3
View File
@@ -223,9 +223,12 @@ struct SharedRegionRegister
// Returns the key of the region with the given name
RegionID Find(const std::string &name) const
{
auto iter = std::find_if(regions.begin(), regions.end(), [&](const auto &region) {
return std::strncmp(region.name, name.c_str(), SharedRegion::MAX_NAME_LENGTH) == 0;
});
auto iter = std::find_if(
regions.begin(),
regions.end(),
[&](const auto &region) {
return std::strncmp(region.name, name.c_str(), SharedRegion::MAX_NAME_LENGTH) == 0;
});
if (iter == regions.end())
{
+2 -1
View File
@@ -113,7 +113,8 @@ class SharedMemory
{
auto shmid = shm.get_shmid();
::shmid_ds xsi_ds;
const auto errorToMessage = [](int error) -> std::string {
const auto errorToMessage = [](int error) -> std::string
{
switch (error)
{
case EPERM:
+3 -3
View File
@@ -241,9 +241,9 @@ inline auto make_contracted_metric_view(const SharedDataIndex &index, const std:
std::vector<util::vector_view<bool>> edge_filter;
index.List(name + "/exclude",
boost::make_function_output_iterator([&](const auto &filter_name) {
edge_filter.push_back(make_vector_view<bool>(index, filter_name));
}));
boost::make_function_output_iterator(
[&](const auto &filter_name)
{ edge_filter.push_back(make_vector_view<bool>(index, filter_name)); }));
return contractor::ContractedMetricView{{node_list, edge_list}, std::move(edge_filter)};
}
+22 -17
View File
@@ -46,31 +46,36 @@ template <typename Key, typename Value> struct CSVFilesParser
{
tbb::spin_mutex mutex;
std::vector<std::pair<Key, Value>> lookup;
tbb::parallel_for(std::size_t{0}, csv_filenames.size(), [&](const std::size_t idx) {
auto local = ParseCSVFile(csv_filenames[idx], start_index + idx);
tbb::parallel_for(std::size_t{0},
csv_filenames.size(),
[&](const std::size_t idx)
{
auto local = ParseCSVFile(csv_filenames[idx], start_index + idx);
{ // Merge local CSV results into a flat global vector
tbb::spin_mutex::scoped_lock _{mutex};
lookup.insert(end(lookup),
std::make_move_iterator(begin(local)),
std::make_move_iterator(end(local)));
}
});
{ // Merge local CSV results into a flat global vector
tbb::spin_mutex::scoped_lock _{mutex};
lookup.insert(end(lookup),
std::make_move_iterator(begin(local)),
std::make_move_iterator(end(local)));
}
});
// With flattened map-ish view of all the files, make a stable sort on key and source
// and unique them on key to keep only the value with the largest file index
// and the largest line number in a file.
// The operands order is swapped to make descending ordering on (key, source)
tbb::parallel_sort(begin(lookup), end(lookup), [](const auto &lhs, const auto &rhs) {
return std::tie(rhs.first, rhs.second.source) <
std::tie(lhs.first, lhs.second.source);
});
tbb::parallel_sort(begin(lookup),
end(lookup),
[](const auto &lhs, const auto &rhs) {
return std::tie(rhs.first, rhs.second.source) <
std::tie(lhs.first, lhs.second.source);
});
// Unique only on key to take the source precedence into account and remove duplicates.
const auto it =
std::unique(begin(lookup), end(lookup), [](const auto &lhs, const auto &rhs) {
return lhs.first == rhs.first;
});
const auto it = std::unique(begin(lookup),
end(lookup),
[](const auto &lhs, const auto &rhs)
{ return lhs.first == rhs.first; });
lookup.erase(it, end(lookup));
util::Log() << "In total loaded " << csv_filenames.size() << " file(s) with a total of "
+5 -4
View File
@@ -15,10 +15,11 @@ template <typename Key, typename Value> struct LookupTable
boost::optional<Value> operator()(const Key &key) const
{
using Result = boost::optional<Value>;
const auto it = std::lower_bound(
lookup.begin(), lookup.end(), key, [](const auto &lhs, const auto &rhs) {
return rhs < lhs.first;
});
const auto it =
std::lower_bound(lookup.begin(),
lookup.end(),
key,
[](const auto &lhs, const auto &rhs) { return rhs < lhs.first; });
return it != std::end(lookup) && !(it->first < key) ? Result(it->second) : Result();
}
+1 -1
View File
@@ -46,7 +46,7 @@ template <typename From, typename Tag> struct Alias final
static_assert(std::is_arithmetic<From>::value, "Needs to be based on an arithmetic type");
From __value;
friend std::ostream &operator<<<From, Tag>(std::ostream &stream, const Alias &inst);
friend std::ostream &operator<< <From, Tag>(std::ostream &stream, const Alias &inst);
explicit operator From &() { return __value; }
explicit operator From() const { return __value; }
+31 -25
View File
@@ -179,7 +179,8 @@ template <class BinaryOperation, typename iterator_type>
double getLength(iterator_type begin, const iterator_type end, BinaryOperation op)
{
double result = 0;
const auto functor = [&result, op](const Coordinate lhs, const Coordinate rhs) {
const auto functor = [&result, op](const Coordinate lhs, const Coordinate rhs)
{
result += op(lhs, rhs);
return false;
};
@@ -197,8 +198,9 @@ findClosestDistance(const Coordinate coordinate, const iterator_type begin, cons
double current_min = std::numeric_limits<double>::max();
// comparator updating current_min without ever finding an element
const auto compute_minimum_distance = [&current_min, coordinate](const Coordinate lhs,
const Coordinate rhs) {
const auto compute_minimum_distance =
[&current_min, coordinate](const Coordinate lhs, const Coordinate rhs)
{
current_min = std::min(current_min, findClosestDistance(coordinate, lhs, rhs));
return false;
};
@@ -216,8 +218,9 @@ double findClosestDistance(const iterator_type lhs_begin,
{
double current_min = std::numeric_limits<double>::max();
const auto compute_minimum_distance_in_rhs = [&current_min, rhs_begin, rhs_end](
const Coordinate coordinate) {
const auto compute_minimum_distance_in_rhs =
[&current_min, rhs_begin, rhs_end](const Coordinate coordinate)
{
current_min = std::min(current_min, findClosestDistance(coordinate, rhs_begin, rhs_end));
return false;
};
@@ -233,13 +236,11 @@ std::pair<Coordinate, Coordinate> leastSquareRegression(const iterator_type begi
// following the formulas of https://faculty.elgin.edu/dkernler/statistics/ch04/4-2.html
const auto number_of_coordinates = std::distance(begin, end);
BOOST_ASSERT(number_of_coordinates >= 2);
const auto extract_lon = [](const Coordinate coordinate) {
return static_cast<double>(toFloating(coordinate.lon));
};
const auto extract_lon = [](const Coordinate coordinate)
{ return static_cast<double>(toFloating(coordinate.lon)); };
const auto extract_lat = [](const Coordinate coordinate) {
return static_cast<double>(toFloating(coordinate.lat));
};
const auto extract_lat = [](const Coordinate coordinate)
{ return static_cast<double>(toFloating(coordinate.lat)); };
double min_lon = extract_lon(*begin);
double max_lon = extract_lon(*begin);
@@ -262,19 +263,21 @@ std::pair<Coordinate, Coordinate> leastSquareRegression(const iterator_type begi
{
std::vector<util::Coordinate> rotated_coordinates(number_of_coordinates);
// rotate all coordinates to the right
std::transform(begin, end, rotated_coordinates.begin(), [](const auto coordinate) {
return rotateCCWAroundZero(coordinate, detail::degToRad(-90));
});
std::transform(begin,
end,
rotated_coordinates.begin(),
[](const auto coordinate)
{ return rotateCCWAroundZero(coordinate, detail::degToRad(-90)); });
const auto rotated_regression =
leastSquareRegression(rotated_coordinates.begin(), rotated_coordinates.end());
return {rotateCCWAroundZero(rotated_regression.first, detail::degToRad(90)),
rotateCCWAroundZero(rotated_regression.second, detail::degToRad(90))};
}
const auto make_accumulate = [](const auto extraction_function) {
return [extraction_function](const double sum_so_far, const Coordinate coordinate) {
return sum_so_far + extraction_function(coordinate);
};
const auto make_accumulate = [](const auto extraction_function)
{
return [extraction_function](const double sum_so_far, const Coordinate coordinate)
{ return sum_so_far + extraction_function(coordinate); };
};
const auto accumulated_lon = std::accumulate(begin, end, 0., make_accumulate(extract_lon));
@@ -283,8 +286,10 @@ std::pair<Coordinate, Coordinate> leastSquareRegression(const iterator_type begi
const auto mean_lon = accumulated_lon / number_of_coordinates;
const auto mean_lat = accumulated_lat / number_of_coordinates;
const auto make_variance = [](const auto mean, const auto extraction_function) {
return [extraction_function, mean](const double sum_so_far, const Coordinate coordinate) {
const auto make_variance = [](const auto mean, const auto extraction_function)
{
return [extraction_function, mean](const double sum_so_far, const Coordinate coordinate)
{
const auto difference = extraction_function(coordinate) - mean;
return sum_so_far + difference * difference;
};
@@ -312,7 +317,8 @@ std::pair<Coordinate, Coordinate> leastSquareRegression(const iterator_type begi
std::accumulate(begin,
end,
0.,
[&](const auto sum_so_far, const auto current_coordinate) {
[&](const auto sum_so_far, const auto current_coordinate)
{
return sum_so_far + (extract_lon(current_coordinate) - mean_lon) *
(extract_lat(current_coordinate) - mean_lat) /
(sample_variance_lon * sample_variance_lat);
@@ -323,9 +329,8 @@ std::pair<Coordinate, Coordinate> leastSquareRegression(const iterator_type begi
const auto intercept = mean_lat - slope * mean_lon;
const auto GetLatAtLon = [intercept,
slope](const util::FloatLongitude longitude) -> util::FloatLatitude {
return {intercept + slope * static_cast<double>((longitude))};
};
slope](const util::FloatLongitude longitude) -> util::FloatLatitude
{ return {intercept + slope * static_cast<double>((longitude))}; };
const double offset = 0.00001;
const Coordinate regression_first = {
@@ -359,7 +364,8 @@ bool areParallel(const iterator_type lhs_begin,
const auto rotation_angle_radians = detail::degToRad(bearing_lhs - 90);
const auto rotated_difference_rhs = rotateCCWAroundZero(difference_rhs, rotation_angle_radians);
const auto get_slope = [](const Coordinate from, const Coordinate to) {
const auto get_slope = [](const Coordinate from, const Coordinate to)
{
const auto diff_lat = static_cast<int>(from.lat) - static_cast<int>(to.lat);
const auto diff_lon = static_cast<int>(from.lon) - static_cast<int>(to.lon);
if (diff_lon == 0)
+1 -1
View File
@@ -254,7 +254,7 @@ template <typename ElementT> class DeallocatingVector
++current_size;
}
template <typename... Ts> void emplace_back(Ts &&... element)
template <typename... Ts> void emplace_back(Ts &&...element)
{
const std::size_t current_capacity = capacity();
if (current_size == current_capacity)
+22 -19
View File
@@ -68,7 +68,7 @@ template <typename EdgeDataT> class DynamicGraph
}
template <typename... Ts>
InputEdge(NodeIterator source, NodeIterator target, Ts &&... data)
InputEdge(NodeIterator source, NodeIterator target, Ts &&...data)
: source(source), target(target), data(std::forward<Ts>(data)...)
{
}
@@ -189,25 +189,28 @@ template <typename EdgeDataT> class DynamicGraph
other.node_array.resize(node_array.size());
NodeID node_id = 0;
std::transform(
node_array.begin(), node_array.end(), other.node_array.begin(), [&](const Node &node) {
const EdgeIterator first_edge = other.edge_list.size();
std::transform(node_array.begin(),
node_array.end(),
other.node_array.begin(),
[&](const Node &node)
{
const EdgeIterator first_edge = other.edge_list.size();
BOOST_ASSERT(node_id < number_of_nodes);
if (filter(node_id++))
{
std::copy_if(edge_list.begin() + node.first_edge,
edge_list.begin() + node.first_edge + node.edges,
std::back_inserter(other.edge_list),
[&](const auto &edge) { return filter(edge.target); });
const unsigned num_edges = other.edge_list.size() - first_edge;
return Node{first_edge, num_edges};
}
else
{
return Node{first_edge, 0};
}
});
BOOST_ASSERT(node_id < number_of_nodes);
if (filter(node_id++))
{
std::copy_if(edge_list.begin() + node.first_edge,
edge_list.begin() + node.first_edge + node.edges,
std::back_inserter(other.edge_list),
[&](const auto &edge) { return filter(edge.target); });
const unsigned num_edges = other.edge_list.size() - first_edge;
return Node{first_edge, num_edges};
}
else
{
return Node{first_edge, 0};
}
});
return other;
}
+3 -3
View File
@@ -37,9 +37,9 @@ class FilteredGraphImpl<util::StaticGraph<EdgeDataT, Ownership>, Ownership>
unsigned GetOutDegree(const NodeIterator n) const
{
auto range = graph.GetAdjacentEdgeRange(n);
return std::count_if(range.begin(), range.end(), [this](const EdgeIterator edge) {
return edge_filter[edge];
});
return std::count_if(range.begin(),
range.end(),
[this](const EdgeIterator edge) { return edge_filter[edge]; });
}
inline NodeIterator GetTarget(const EdgeIterator e) const
+3 -3
View File
@@ -58,7 +58,7 @@ class GeojsonLogger
}
// writes a single feature into the Geojson file
template <typename... Args> static bool Write(Args &&... args)
template <typename... Args> static bool Write(Args &&...args)
{
// make sure to syncronize logging output, our writing should be sequential
std::lock_guard<std::mutex> guard(lock);
@@ -146,7 +146,7 @@ class ScopedGeojsonLoggerGuard
{
public:
template <typename... Args>
ScopedGeojsonLoggerGuard(const std::string &logfile, Args &&... args)
ScopedGeojsonLoggerGuard(const std::string &logfile, Args &&...args)
: policy(std::forward<Args>(args)...)
{
GeojsonLogger<geojson_conversion_policy, scenario>::Open(logfile);
@@ -159,7 +159,7 @@ class ScopedGeojsonLoggerGuard
GeojsonLogger<geojson_conversion_policy, scenario>::SetPolicy(nullptr);
}
template <typename... Args> static bool Write(Args &&... args)
template <typename... Args> static bool Write(Args &&...args)
{
return GeojsonLogger<geojson_conversion_policy, scenario>::Write(
std::forward<Args>(args)...);
+10 -8
View File
@@ -63,14 +63,16 @@ template <typename StringView> inline auto decompose(const StringView &lhs, cons
auto const lcs = longest_common_substring(lhs, rhs);
// trim spaces, transform to lower
const auto trim = [](StringView view) {
const auto trim = [](StringView view)
{
// we compare suffixes based on this value, it might break UTF chars, but as long as we are
// consistent in handling, we do not create bad results
std::string str;
str.reserve(view.size());
std::transform(view.begin(), view.end(), std::back_inserter(str), [](unsigned char c) {
return std::tolower(c);
});
std::transform(view.begin(),
view.end(),
std::back_inserter(str),
[](unsigned char c) { return std::tolower(c); });
auto front = str.find_first_not_of(' ');
if (front == std::string::npos)
@@ -131,13 +133,13 @@ inline bool requiresNameAnnounced(const StringView &from_name,
const auto checkForPrefixOrSuffixChange = [](const std::string_view first,
const std::string_view second,
const SuffixTable &suffix_table) {
const SuffixTable &suffix_table)
{
std::string first_prefix, first_suffix, second_prefix, second_suffix;
std::tie(first_prefix, first_suffix, second_prefix, second_suffix) =
decompose(first, second);
const auto checkTable = [&](const std::string &str) {
return str.empty() || suffix_table.isSuffix(str);
};
const auto checkTable = [&](const std::string &str)
{ return str.empty() || suffix_table.isSuffix(str); };
return checkTable(first_prefix) && checkTable(first_suffix) && checkTable(second_prefix) &&
checkTable(second_suffix);
+2 -3
View File
@@ -315,9 +315,8 @@ template <typename GroupBlockPolicy, storage::Ownership Ownership> struct Indexe
values_byte_iter = block.WriteBlockPrefix(curr, next, values_byte_iter);
std::advance(next, std::min<diff_type>(1, std::distance(next, sentinel)));
auto to_bytes = [&](const auto &data) {
values_byte_iter = std::copy_n(&data, sizeof(ValueType), values_byte_iter);
};
auto to_bytes = [&](const auto &data)
{ values_byte_iter = std::copy_n(&data, sizeof(ValueType), values_byte_iter); };
std::copy(data + *curr,
data + *next,
boost::make_function_output_iterator(std::cref(to_bytes)));
+4 -5
View File
@@ -43,11 +43,10 @@ class integer_iterator : public boost::iterator_facade<integer_iterator<Integer>
difference_type distance_to(const integer_iterator &other) const
{
return std::is_signed<value_type>::value
? (other.m_value - m_value)
: (other.m_value >= m_value)
? static_cast<difference_type>(other.m_value - m_value)
: -static_cast<difference_type>(m_value - other.m_value);
return std::is_signed<value_type>::value ? (other.m_value - m_value)
: (other.m_value >= m_value)
? static_cast<difference_type>(other.m_value - m_value)
: -static_cast<difference_type>(m_value - other.m_value);
}
friend class ::boost::iterator_core_access;
+1 -1
View File
@@ -8,7 +8,7 @@ extern "C"
#include <lualib.h>
}
#include <boost/filesystem/convenience.hpp>
#include <boost/filesystem.hpp>
#include <iostream>
#include <string>
+2 -1
View File
@@ -79,7 +79,8 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
auto edges_list = directedEdgesFromCompressed<NodeBasedDynamicGraph::InputEdge>(
input_edge_list,
[](NodeBasedDynamicGraph::InputEdge &output_edge,
const extractor::NodeBasedEdge &input_edge) {
const extractor::NodeBasedEdge &input_edge)
{
output_edge.data.weight = input_edge.weight;
output_edge.data.duration = input_edge.duration;
output_edge.data.distance = input_edge.distance;
+6 -9
View File
@@ -193,23 +193,20 @@ struct OpeningHours
&& (times.empty() ||
std::any_of(times.begin(),
times.end(),
[&time, &use_curr_day, &use_next_day](const auto &x) {
return x.IsInRange(time, use_curr_day, use_next_day);
}))
[&time, &use_curr_day, &use_next_day](const auto &x)
{ return x.IsInRange(time, use_curr_day, use_next_day); }))
// .. and if weekdays are not specified or matches weekdays range
&& (weekdays.empty() ||
std::any_of(weekdays.begin(),
weekdays.end(),
[&time, use_curr_day, use_next_day](const auto &x) {
return x.IsInRange(time, use_curr_day, use_next_day);
}))
[&time, use_curr_day, use_next_day](const auto &x)
{ return x.IsInRange(time, use_curr_day, use_next_day); }))
// .. and if month-day ranges are not specified or is in any month-day range
&& (monthdays.empty() ||
std::any_of(monthdays.begin(),
monthdays.end(),
[&time, use_curr_day, use_next_day](const auto &x) {
return x.IsInRange(time, use_curr_day, use_next_day);
}));
[&time, use_curr_day, use_next_day](const auto &x)
{ return x.IsInRange(time, use_curr_day, use_next_day); }));
}
std::vector<TimeSpan> times;
+3 -3
View File
@@ -345,9 +345,9 @@ class QueryHeap
void DeleteAll()
{
auto const none_handle = heap.s_handle_from_iterator(heap.end());
std::for_each(inserted_nodes.begin(), inserted_nodes.end(), [&none_handle](auto &node) {
node.handle = none_handle;
});
std::for_each(inserted_nodes.begin(),
inserted_nodes.end(),
[&none_handle](auto &node) { node.handle = none_handle; });
heap.clear();
}
+2 -1
View File
@@ -64,7 +64,8 @@ template <unsigned BLOCK_SIZE, storage::Ownership Ownership> class RangeTable
// construct table from length vector
template <typename VectorT> explicit RangeTable(const VectorT &lengths)
{
const unsigned number_of_blocks = [&lengths]() {
const unsigned number_of_blocks = [&lengths]()
{
unsigned num = (lengths.size() + 1) / (BLOCK_SIZE + 1);
if ((lengths.size() + 1) % (BLOCK_SIZE + 1) != 0)
{
+9 -5
View File
@@ -94,7 +94,7 @@ template <typename EdgeDataT> struct SortableEdgeWithData : SortableEdgeWithData
SortableEdgeWithData() = default;
template <typename... Ts>
SortableEdgeWithData(NodeIterator source, NodeIterator target, Ts &&... data)
SortableEdgeWithData(NodeIterator source, NodeIterator target, Ts &&...data)
: Base{source, target}, data{std::forward<Ts>(data)...}
{
}
@@ -304,10 +304,14 @@ class StaticGraph
BOOST_ASSERT(node_array.size() == number_of_nodes + 1);
edge_array.resize(number_of_edges);
std::transform(begin, end, edge_array.begin(), [](const auto &from) {
return static_graph_details::edgeToEntry<EdgeArrayEntry>(
from, traits::HasDataMember<EdgeArrayEntry>{});
});
std::transform(begin,
end,
edge_array.begin(),
[](const auto &from)
{
return static_graph_details::edgeToEntry<EdgeArrayEntry>(
from, traits::HasDataMember<EdgeArrayEntry>{});
});
}
protected:
+4 -4
View File
@@ -281,7 +281,8 @@ class StaticRTree
tbb::parallel_for(
tbb::blocked_range<uint64_t>(0, element_count),
[&input_data_vector, &input_wrapper_vector, this](
const tbb::blocked_range<uint64_t> &range) {
const tbb::blocked_range<uint64_t> &range)
{
for (uint64_t element_counter = range.begin(), end = range.end();
element_counter != end;
++element_counter)
@@ -560,9 +561,8 @@ class StaticRTree
return Nearest(
input_coordinate,
[](const CandidateSegment &) { return std::make_pair(true, true); },
[max_results](const std::size_t num_results, const CandidateSegment &) {
return num_results >= max_results;
});
[max_results](const std::size_t num_results, const CandidateSegment &)
{ return num_results >= max_results; });
}
// Return edges in distance order with the coordinate of the closest point on the edge.
+2 -2
View File
@@ -14,13 +14,13 @@ template <typename T> void hash_combine(std::size_t &seed, const T &val)
template <typename T> void hash_val(std::size_t &seed, const T &val) { hash_combine(seed, val); }
template <typename T, typename... Types>
void hash_val(std::size_t &seed, const T &val, const Types &... args)
void hash_val(std::size_t &seed, const T &val, const Types &...args)
{
hash_combine(seed, val);
hash_val(seed, args...);
}
template <typename... Types> std::size_t hash_val(const Types &... args)
template <typename... Types> std::size_t hash_val(const Types &...args)
{
std::size_t seed = 0;
hash_val(seed, args...);
+2 -1
View File
@@ -18,7 +18,8 @@ template <int length, int precision> char *printInt(char *buffer, int value)
static_assert(length > 0, "length must be positive");
static_assert(precision > 0, "precision must be positive");
const bool minus = [&value] {
const bool minus = [&value]
{
if (value >= 0)
{
value = -value;
+13 -9
View File
@@ -51,16 +51,20 @@ template <std::size_t TimeBinSize = 1000, std::size_t IndexBinSize = 1000> class
{
std::stringstream out;
const auto print_bins = [&out](auto frame_index, auto begin, auto end) {
const auto print_bins = [&out](auto frame_index, auto begin, auto end)
{
auto bin_index = 0;
std::for_each(begin, end, [&](const auto count) {
if (count > 0)
{
out << (frame_index * TimeBinSize) << "," << (bin_index * IndexBinSize) << ","
<< count << std::endl;
}
bin_index++;
});
std::for_each(begin,
end,
[&](const auto count)
{
if (count > 0)
{
out << (frame_index * TimeBinSize) << ","
<< (bin_index * IndexBinSize) << "," << count << std::endl;
}
bin_index++;
});
};
if (frame_offsets.size() == 0)
View File
-6
View File
@@ -1,6 +0,0 @@
#!/bin/sh -ex
sudo dpkg --add-architecture i386
sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test && ( sudo apt-get update -qq --yes || true )
sudo apt-get install -qq --yes --force-yes g++-9-multilib libxml2-dev:i386 libexpat1-dev:i386 libzip-dev:i386 libbz2-dev:i386 libtbb-dev:i386 lua5.2:i386 liblua5.2-dev:i386 libboost-date-time-dev:i386 libboost-filesystem-dev:i386 libboost-iostreams-dev:i386 libboost-program-options-dev:i386 libboost-regex-dev:i386 libboost-system-dev:i386 libboost-thread-dev:i386 libboost-test-dev:i386
-5
View File
@@ -12,11 +12,6 @@ if [[ ${BUILD_TYPE} == "Debug" ]]; then
NPM_FLAGS='--debug'
fi
# append --target_arch in order to handle cross-compilation for Apple Silicon
if [[ "$ENABLE_APPLE_SILICON" == "ON" ]]; then
NPM_FLAGS="${NPM_FLAGS} --target_arch=arm64"
fi
echo "dumping binary meta..."
./node_modules/.bin/node-pre-gyp reveal $NPM_FLAGS
+2 -1
View File
@@ -1,3 +1,4 @@
alignment:src/contractor/graph_contractor.cpp
enum:include/tbb/pipeline.h
vptr:src/util/log.cpp
vptr:include/tbb/task.h
@@ -13,4 +14,4 @@ signed-integer-overflow:include/engine/internal_route_result.hpp
pointer-overflow:third_party/sol2/sol/stack_core.hpp
pointer-overflow:third_party/rapidjson/include/rapidjson/internal/stack.h
nonnull-attribute:third_party/microtar/src/microtar.c
integer-divide-by-zero:unit_tests/library/route.cpp
integer-divide-by-zero:unit_tests/library/route.cpp
+1 -1
View File
@@ -21,7 +21,7 @@ msbuild OSRM.sln ^
/p:BuildInParallel=true ^
/m:%NUMBER_OF_PROCESSORS% ^
/toolsversion:Current ^
/clp:Verbosity=normal ^
/clp:Verbosity=quiet ^
/nologo
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
+5 -5
View File
@@ -19,18 +19,18 @@ elif [[ ${OS} = "Darwin" ]] ; then
fi
# Discover clang-format
if type clang-format-10 2> /dev/null ; then
CLANG_FORMAT=clang-format-10
if type clang-format-15 2> /dev/null ; then
CLANG_FORMAT=clang-format-15
elif type clang-format 2> /dev/null ; then
# Clang format found, but need to check version
CLANG_FORMAT=clang-format
V=$(clang-format --version)
if [[ $V != *10.0* ]] ; then
echo "clang-format is not 10.0 (returned ${V})"
if [[ $V != *15.0* ]] ; then
echo "clang-format is not 15.0 (returned ${V})"
#exit 1
fi
else
echo "No appropriate clang-format found (expected clang-format-10, or clang-format)"
echo "No appropriate clang-format found (expected clang-format-15, or clang-format)"
exit 1
fi
-23
View File
@@ -1,23 +0,0 @@
#!/usr/bin/env bash
set -o errexit
set -o pipefail
set -o nounset
# Runs the Clang Modernizer in parallel on the code base.
# Requires a compilation database in the build directory.
find src include unit_tests -type f -name '*.hpp' -o -name '*.cpp' \
| xargs \
-I{} \
-P $(nproc) \
clang-modernize \
-p build \
-final-syntax-check \
-format \
-style=file \
-summary \
-for-compilers=clang-3.4,gcc-4.8 \
-include . \
-exclude third_party \
{}
+5 -2
View File
@@ -28,7 +28,10 @@ PROTOZERO_PATH="mapbox/protozero"
PROTOZERO_TAG=v1.6.2
VTZERO_PATH="mapbox/vtzero"
VTZERO_TAG=v1.0.1
VTZERO_TAG=v1.1.0
FMT_PATH="fmtlib/fmt"
FMT_TAG=v10.2.1
function update_subtree () {
name=${1^^}
@@ -53,6 +56,6 @@ function update_subtree () {
}
## Update dependencies
for dep in osmium variant sol rapidjson microtar protozero vtzero ; do
for dep in osmium variant sol rapidjson microtar protozero vtzero fmt; do
update_subtree $dep
done
+3
View File
@@ -1,3 +1,4 @@
#include "engine/engine_config.hpp"
#include "util/timing_util.hpp"
#include "osrm/match_parameters.hpp"
@@ -32,6 +33,8 @@ try
// Configure based on a .osrm base path, and no datasets in shared mem from osrm-datastore
EngineConfig config;
config.storage_config = {argv[1]};
config.algorithm = (argc > 2 && std::string{argv[2]} == "mld") ? EngineConfig::Algorithm::MLD
: EngineConfig::Algorithm::CH;
config.use_shared_memory = false;
// Routing machine with several services (such as Route, Table, Nearest, Trip, Match)
+6 -6
View File
@@ -65,12 +65,12 @@ void benchmark(BenchStaticRTree &rtree, unsigned num_queries)
util::FixedLatitude{lat_udist(mt_rand)});
}
benchmarkQuery(queries, "raw RTree queries (1 result)", [&rtree](const util::Coordinate &q) {
return rtree.Nearest(q, 1);
});
benchmarkQuery(queries, "raw RTree queries (10 results)", [&rtree](const util::Coordinate &q) {
return rtree.Nearest(q, 10);
});
benchmarkQuery(queries,
"raw RTree queries (1 result)",
[&rtree](const util::Coordinate &q) { return rtree.Nearest(q, 1); });
benchmarkQuery(queries,
"raw RTree queries (10 results)",
[&rtree](const util::Coordinate &q) { return rtree.Nearest(q, 10); });
}
} // namespace osrm::benchmarks
+20 -12
View File
@@ -619,7 +619,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
util::UnbufferedLog log;
log << "initializing node priorities...";
tbb::parallel_for(tbb::blocked_range<std::size_t>(0, remaining_nodes.size(), PQGrainSize),
[&](const auto &range) {
[&](const auto &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
for (auto x = range.begin(), end = range.end(); x != end; ++x)
{
@@ -656,7 +657,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
tbb::parallel_for(
tbb::blocked_range<NodeID>(0, remaining_nodes.size(), IndependentGrainSize),
[&](const auto &range) {
[&](const auto &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
// determine independent node set
for (auto i = range.begin(), end = range.end(); i != end; ++i)
@@ -669,9 +671,9 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
// sort all remaining nodes to the beginning of the sequence
const auto begin_independent_nodes = std::stable_partition(
remaining_nodes.begin(), remaining_nodes.end(), [](RemainingNodeData node_data) {
return !node_data.is_independent;
});
remaining_nodes.begin(),
remaining_nodes.end(),
[](RemainingNodeData node_data) { return !node_data.is_independent; });
auto begin_independent_nodes_idx =
std::distance(remaining_nodes.begin(), begin_independent_nodes);
auto end_independent_nodes_idx = remaining_nodes.size();
@@ -680,7 +682,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
tbb::parallel_for(
tbb::blocked_range<NodeID>(
begin_independent_nodes_idx, end_independent_nodes_idx, ContractGrainSize),
[&](const auto &range) {
[&](const auto &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
for (auto position = range.begin(), end = range.end(); position != end; ++position)
{
@@ -699,7 +702,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
tbb::parallel_for(
tbb::blocked_range<NodeID>(
begin_independent_nodes_idx, end_independent_nodes_idx, DeleteGrainSize),
[&](const auto &range) {
[&](const auto &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
for (auto position = range.begin(), end = range.end(); position != end; ++position)
{
@@ -709,10 +713,13 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
});
// make sure we really sort each block
tbb::parallel_for(thread_data_list.data.range(), [&](const auto &range) {
for (auto &data : range)
tbb::parallel_sort(data->inserted_edges.begin(), data->inserted_edges.end());
});
tbb::parallel_for(thread_data_list.data.range(),
[&](const auto &range)
{
for (auto &data : range)
tbb::parallel_sort(data->inserted_edges.begin(),
data->inserted_edges.end());
});
// insert new edges
for (auto &data : thread_data_list.data)
@@ -743,7 +750,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
tbb::parallel_for(
tbb::blocked_range<NodeID>(
begin_independent_nodes_idx, end_independent_nodes_idx, NeighboursGrainSize),
[&](const auto &range) {
[&](const auto &range)
{
ContractorThreadData *data = thread_data_list.GetThreadData();
for (auto position = range.begin(), end = range.end(); position != end; ++position)
{
+7 -6
View File
@@ -47,17 +47,18 @@ void printUnreachableStatistics(const Partition &partition,
for (auto node : cell.GetSourceNodes())
{
const auto &weights = cell.GetOutWeight(node);
invalid_sources += std::all_of(weights.begin(), weights.end(), [](auto weight) {
return weight == INVALID_EDGE_WEIGHT;
});
invalid_sources +=
std::all_of(weights.begin(),
weights.end(),
[](auto weight) { return weight == INVALID_EDGE_WEIGHT; });
}
for (auto node : cell.GetDestinationNodes())
{
const auto &weights = cell.GetInWeight(node);
invalid_destinations +=
std::all_of(weights.begin(), weights.end(), [](auto weight) {
return weight == INVALID_EDGE_WEIGHT;
});
std::all_of(weights.begin(),
weights.end(),
[](auto weight) { return weight == INVALID_EDGE_WEIGHT; });
}
}
+7 -6
View File
@@ -129,7 +129,8 @@ util::json::Object makeIntersection(const guidance::IntermediateIntersection &in
std::transform(intersection.entry.begin(),
intersection.entry.end(),
std::back_inserter(entry.values),
[](const bool has_entry) -> util::json::Value {
[](const bool has_entry) -> util::json::Value
{
if (has_entry)
return util::json::True();
else
@@ -151,11 +152,11 @@ util::json::Object makeIntersection(const guidance::IntermediateIntersection &in
{
util::json::Array classes;
classes.values.reserve(intersection.classes.size());
std::transform(
intersection.classes.begin(),
intersection.classes.end(),
std::back_inserter(classes.values),
[](const std::string &class_name) { return util::json::String{class_name}; });
std::transform(intersection.classes.begin(),
intersection.classes.end(),
std::back_inserter(classes.values),
[](const std::string &class_name)
{ return util::json::String{class_name}; });
result.values["classes"] = std::move(classes);
}
+5 -3
View File
@@ -43,9 +43,11 @@ std::vector<util::Coordinate> douglasPeucker(std::vector<util::Coordinate>::cons
}
std::vector<util::FloatCoordinate> projected_coordinates(size);
std::transform(begin, end, projected_coordinates.begin(), [](const util::Coordinate coord) {
return util::web_mercator::fromWGS84(coord);
});
std::transform(begin,
end,
projected_coordinates.begin(),
[](const util::Coordinate coord)
{ return util::web_mercator::fromWGS84(coord); });
std::vector<bool> is_necessary(size, false);
BOOST_ASSERT(is_necessary.size() >= 2);
+2 -3
View File
@@ -9,9 +9,8 @@ bool EngineConfig::IsValid() const
// leads to an empty path
const bool all_path_are_empty = storage_config.GetPath("").empty();
const auto unlimited_or_more_than = [](const auto v, const auto limit) {
return v == -1 || v > limit;
};
const auto unlimited_or_more_than = [](const auto v, const auto limit)
{ return v == -1 || v > limit; };
const bool limits_valid =
unlimited_or_more_than(max_locations_distance_table, 2) &&
+9 -10
View File
@@ -40,22 +40,21 @@ unsigned calculateOverviewZoomLevel(const std::vector<LegGeometry> &leg_geometri
std::vector<util::Coordinate> assembleOverview(const std::vector<LegGeometry> &leg_geometries,
const bool use_simplification)
{
auto overview_size =
std::accumulate(leg_geometries.begin(),
leg_geometries.end(),
0,
[](const std::size_t sum, const LegGeometry &leg_geometry) {
return sum + leg_geometry.locations.size();
}) -
leg_geometries.size() + 1;
auto overview_size = std::accumulate(leg_geometries.begin(),
leg_geometries.end(),
0,
[](const std::size_t sum, const LegGeometry &leg_geometry)
{ return sum + leg_geometry.locations.size(); }) -
leg_geometries.size() + 1;
std::vector<util::Coordinate> overview_geometry;
overview_geometry.reserve(overview_size);
using GeometryIter = decltype(overview_geometry)::const_iterator;
auto leg_reverse_index = leg_geometries.size();
const auto insert_without_overlap = [&leg_reverse_index, &overview_geometry](GeometryIter begin,
GeometryIter end) {
const auto insert_without_overlap =
[&leg_reverse_index, &overview_geometry](GeometryIter begin, GeometryIter end)
{
// not the last leg
if (leg_reverse_index > 1)
{
+15 -12
View File
@@ -7,18 +7,21 @@ namespace osrm::engine::guidance
Route assembleRoute(const std::vector<RouteLeg> &route_legs)
{
auto distance = std::accumulate(
route_legs.begin(), route_legs.end(), 0., [](const double sum, const RouteLeg &leg) {
return sum + leg.distance;
});
auto duration = std::accumulate(
route_legs.begin(), route_legs.end(), 0., [](const double sum, const RouteLeg &leg) {
return sum + leg.duration;
});
auto weight = std::accumulate(
route_legs.begin(), route_legs.end(), 0., [](const double sum, const RouteLeg &leg) {
return sum + leg.weight;
});
auto distance =
std::accumulate(route_legs.begin(),
route_legs.end(),
0.,
[](const double sum, const RouteLeg &leg) { return sum + leg.distance; });
auto duration =
std::accumulate(route_legs.begin(),
route_legs.end(),
0.,
[](const double sum, const RouteLeg &leg) { return sum + leg.duration; });
auto weight =
std::accumulate(route_legs.begin(),
route_legs.end(),
0.,
[](const double sum, const RouteLeg &leg) { return sum + leg.weight; });
return Route{distance, duration, weight};
}
@@ -102,7 +102,8 @@ bool isStaggeredIntersection(const RouteStepIterator step_prior_to_intersection,
// If adjusted, make sure to check validity of the is_right/is_left classification below
const constexpr auto MAX_STAGGERED_DISTANCE = 3; // debatable, but keep short to be on safe side
const auto angle = [](const RouteStep &step) {
const auto angle = [](const RouteStep &step)
{
const auto &intersection = step.intersections.front();
const auto entry_bearing = util::bearing::reverse(intersection.bearings[intersection.in]);
const auto exit_bearing = intersection.bearings[intersection.out];
+12 -6
View File
@@ -59,7 +59,8 @@ double findTotalTurnAngle(const RouteStep &entry_step, const RouteStep &exit_ste
// c
// |
// d
const auto use_total_angle = [&]() {
const auto use_total_angle = [&]()
{
// only consider actual turns in combination:
if (angularDeviation(total_angle, 180) < 0.5 * NARROW_TURN_ANGLE)
return false;
@@ -99,7 +100,8 @@ inline void handleSliproad(RouteStepIterator sliproad_step)
{
// find the next step after the sliproad step itself (this is not necessarily the next step,
// since we might have to skip over traffic lights/node penalties)
auto next_step = [&sliproad_step]() {
auto next_step = [&sliproad_step]()
{
auto next_step = findNextTurn(sliproad_step);
while (isTrafficLightStep(*next_step))
{
@@ -196,7 +198,8 @@ void AdjustToCombinedTurnStrategy::operator()(RouteStep &step_at_turn_location,
: getTurnDirection(angle);
// a turn that is a new name or straight (turn/continue)
const auto is_non_turn = [](const RouteStep &step) {
const auto is_non_turn = [](const RouteStep &step)
{
return hasTurnType(step, TurnType::NewName) ||
(hasTurnType(step, TurnType::Turn) &&
hasModifier(step, DirectionModifier::Straight)) ||
@@ -307,7 +310,8 @@ void SegregatedTurnStrategy::operator()(RouteStep &step_at_turn_location,
// Used to control updating of the modifier based on turn direction
bool update_modifier_for_turn_direction = true;
const auto calculate_turn_angle = [](const RouteStep &entry_step, const RouteStep &exit_step) {
const auto calculate_turn_angle = [](const RouteStep &entry_step, const RouteStep &exit_step)
{
return util::bearing::angleBetween(entry_step.maneuver.bearing_before,
exit_step.maneuver.bearing_after);
};
@@ -316,7 +320,8 @@ void SegregatedTurnStrategy::operator()(RouteStep &step_at_turn_location,
const auto turn_angle = calculate_turn_angle(step_at_turn_location, transfer_from_step);
const auto turn_direction = getTurnDirection(turn_angle);
const auto is_straight_step = [](const RouteStep &step) {
const auto is_straight_step = [](const RouteStep &step)
{
return ((hasTurnType(step, TurnType::NewName) || hasTurnType(step, TurnType::Continue) ||
hasTurnType(step, TurnType::Suppressed) || hasTurnType(step, TurnType::Turn)) &&
(hasModifier(step, DirectionModifier::Straight) ||
@@ -324,7 +329,8 @@ void SegregatedTurnStrategy::operator()(RouteStep &step_at_turn_location,
hasModifier(step, DirectionModifier::SlightRight)));
};
const auto is_turn_step = [](const RouteStep &step) {
const auto is_turn_step = [](const RouteStep &step)
{
return (hasTurnType(step, TurnType::Turn) || hasTurnType(step, TurnType::Continue) ||
hasTurnType(step, TurnType::NewName) || hasTurnType(step, TurnType::Suppressed));
};
+123 -112
View File
@@ -17,7 +17,8 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
const double min_distance_needed_for_lane_change)
{
// Lane anticipation works on contiguous ranges of short steps that have lane information
const auto is_short_has_lanes = [&](const RouteStep &step) {
const auto is_short_has_lanes = [&](const RouteStep &step)
{
const auto has_lanes = step.intersections.front().lanes.lanes_in_turn > 0;
if (!has_lanes)
@@ -45,7 +46,8 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
std::vector<StepIterRange> quick_lanes_ranges;
const auto range_back_inserter = [&](StepIterRange range) {
const auto range_back_inserter = [&](StepIterRange range)
{
if (std::distance(range.first, range.second) > 1)
quick_lanes_ranges.push_back(std::move(range));
};
@@ -58,7 +60,8 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
// Walk backwards over all turns, constraining possible turn lanes.
// Later turn lanes constrain earlier ones: we have to anticipate lane changes.
const auto constrain_lanes = [&](const StepIterRange &turns) {
const auto constrain_lanes = [&](const StepIterRange &turns)
{
const std::reverse_iterator<StepIter> rev_first{turns.second};
const std::reverse_iterator<StepIter> rev_last{turns.first};
@@ -74,127 +77,135 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
// segment for a lane switch, but the total distance shouldn't be unlimited.
double distance_to_constrained = 0.0;
util::for_each_pair(rev_first, rev_last, [&](RouteStep &current, RouteStep &previous) {
const auto current_inst = current.maneuver.instruction;
const auto current_lanes = current.intersections.front().lanes;
// Constrain the previous turn's lanes
auto &previous_lanes = previous.intersections.front().lanes;
const auto previous_inst = previous.maneuver.instruction;
// Lane mapping (N:M) from previous lanes (N) to current lanes (M), with:
// N > M, N > 1 fan-in situation, constrain N lanes to min(N,M) shared lanes
// otherwise nothing to constrain
const bool lanes_to_constrain = previous_lanes.lanes_in_turn > 1;
const bool lanes_fan_in = previous_lanes.lanes_in_turn > current_lanes.lanes_in_turn;
// only prevent use lanes due to making all turns. don't make turns during curvy
// segments
if (previous_inst.type == TurnType::Suppressed)
distance_to_constrained += previous.distance;
else
distance_to_constrained = 0.;
const auto lane_delta = previous_lanes.lanes_in_turn - current_lanes.lanes_in_turn;
const auto can_make_all_turns =
distance_to_constrained > lane_delta * min_distance_needed_for_lane_change;
if (!lanes_to_constrain || !lanes_fan_in || can_make_all_turns)
return;
// We do not have a mapping from lanes to lanes. All we have is the lanes in the turn
// and all the lanes at that situation. To perfectly handle lane anticipation in cases
// where lanes in the turn fan in but for example the overall lanes at that location
// fan out, we would have to know the asymmetric mapping of lanes. This is currently
// not possible at the moment. In the following we implement a heuristic instead.
const LaneID current_num_lanes_right_of_turn = current.NumLanesToTheRight();
const LaneID current_num_lanes_left_of_turn = current.NumLanesToTheLeft();
// 0/ Tag keep straight with the next turn's direction if available
const auto previous_is_straight =
!isLeftTurn(previous_inst) && !isRightTurn(previous_inst);
if (previous_is_straight)
util::for_each_pair(
rev_first,
rev_last,
[&](RouteStep &current, RouteStep &previous)
{
if (isLeftTurn(current_inst) || is_straight_left.count(&current) > 0)
is_straight_left.insert(&previous);
else if (isRightTurn(current_inst) || is_straight_right.count(&current) > 0)
is_straight_right.insert(&previous);
}
const auto current_inst = current.maneuver.instruction;
const auto current_lanes = current.intersections.front().lanes;
// 1/ How to anticipate left, right:
const auto anticipate_for_left_turn = [&] {
// Current turn is left turn, already keep left during previous turn.
// This implies constraining the rightmost lanes in previous step.
LaneID new_first_lane_from_the_right =
previous_lanes.first_lane_from_the_right // start from rightmost lane
+ previous_lanes.lanes_in_turn // one past leftmost lane
- current_lanes.lanes_in_turn; // back number of new lanes
// Constrain the previous turn's lanes
auto &previous_lanes = previous.intersections.front().lanes;
const auto previous_inst = previous.maneuver.instruction;
// The leftmost target lanes might not be involved in the turn. Figure out
// how many lanes are to the left and not in the turn.
new_first_lane_from_the_right -=
std::min(current_num_lanes_left_of_turn, current_lanes.lanes_in_turn);
// Lane mapping (N:M) from previous lanes (N) to current lanes (M), with:
// N > M, N > 1 fan-in situation, constrain N lanes to min(N,M) shared lanes
// otherwise nothing to constrain
const bool lanes_to_constrain = previous_lanes.lanes_in_turn > 1;
const bool lanes_fan_in =
previous_lanes.lanes_in_turn > current_lanes.lanes_in_turn;
previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
};
// only prevent use lanes due to making all turns. don't make turns during curvy
// segments
if (previous_inst.type == TurnType::Suppressed)
distance_to_constrained += previous.distance;
else
distance_to_constrained = 0.;
const auto anticipate_for_right_turn = [&] {
// Current turn is right turn, already keep right during the previous turn.
// This implies constraining the leftmost lanes in the previous turn step.
LaneID new_first_lane_from_the_right = previous_lanes.first_lane_from_the_right;
const auto lane_delta = previous_lanes.lanes_in_turn - current_lanes.lanes_in_turn;
const auto can_make_all_turns =
distance_to_constrained > lane_delta * min_distance_needed_for_lane_change;
// The rightmost target lanes might not be involved in the turn. Figure out
// how many lanes are to the right and not in the turn.
new_first_lane_from_the_right +=
std::min(current_num_lanes_right_of_turn, current_lanes.lanes_in_turn);
if (!lanes_to_constrain || !lanes_fan_in || can_make_all_turns)
return;
previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
};
// We do not have a mapping from lanes to lanes. All we have is the lanes in the
// turn and all the lanes at that situation. To perfectly handle lane anticipation
// in cases where lanes in the turn fan in but for example the overall lanes at that
// location fan out, we would have to know the asymmetric mapping of lanes. This is
// currently not possible at the moment. In the following we implement a heuristic
// instead.
const LaneID current_num_lanes_right_of_turn = current.NumLanesToTheRight();
const LaneID current_num_lanes_left_of_turn = current.NumLanesToTheLeft();
// 2/ When to anticipate a left, right turn
if (isLeftTurn(current_inst))
anticipate_for_left_turn();
else if (isRightTurn(current_inst))
anticipate_for_right_turn();
else // keepStraight
{
// Heuristic: we do not have a from-lanes -> to-lanes mapping. What we use
// here instead in addition is the number of all lanes (not only the lanes
// in a turn):
//
// -v-v v-v- straight follows
// | | | |
// <- v v -> keep straight here
// | |
// <-| |->
//
// A route from the top left to the bottom right here goes over a keep
// straight. If we handle all keep straights as right turns (in right-sided
// driving), we wrongly guide the user to the rightmost lanes in the first turn.
// Not only is this wrong but the opposite of what we expect.
//
// The following implements a heuristic to determine a keep straight's
// direction in relation to the next step. In the above example we would get:
//
// coming from right, going to left (in direction of way) -> handle as left turn
// 0/ Tag keep straight with the next turn's direction if available
const auto previous_is_straight =
!isLeftTurn(previous_inst) && !isRightTurn(previous_inst);
if (is_straight_left.count(&current) > 0)
if (previous_is_straight)
{
if (isLeftTurn(current_inst) || is_straight_left.count(&current) > 0)
is_straight_left.insert(&previous);
else if (isRightTurn(current_inst) || is_straight_right.count(&current) > 0)
is_straight_right.insert(&previous);
}
// 1/ How to anticipate left, right:
const auto anticipate_for_left_turn = [&]
{
// Current turn is left turn, already keep left during previous turn.
// This implies constraining the rightmost lanes in previous step.
LaneID new_first_lane_from_the_right =
previous_lanes.first_lane_from_the_right // start from rightmost lane
+ previous_lanes.lanes_in_turn // one past leftmost lane
- current_lanes.lanes_in_turn; // back number of new lanes
// The leftmost target lanes might not be involved in the turn. Figure out
// how many lanes are to the left and not in the turn.
new_first_lane_from_the_right -=
std::min(current_num_lanes_left_of_turn, current_lanes.lanes_in_turn);
previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
};
const auto anticipate_for_right_turn = [&]
{
// Current turn is right turn, already keep right during the previous turn.
// This implies constraining the leftmost lanes in the previous turn step.
LaneID new_first_lane_from_the_right = previous_lanes.first_lane_from_the_right;
// The rightmost target lanes might not be involved in the turn. Figure out
// how many lanes are to the right and not in the turn.
new_first_lane_from_the_right +=
std::min(current_num_lanes_right_of_turn, current_lanes.lanes_in_turn);
previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
};
// 2/ When to anticipate a left, right turn
if (isLeftTurn(current_inst))
anticipate_for_left_turn();
else if (is_straight_right.count(&current) > 0)
else if (isRightTurn(current_inst))
anticipate_for_right_turn();
else // FIXME: right-sided driving
anticipate_for_right_turn();
}
else // keepStraight
{
// Heuristic: we do not have a from-lanes -> to-lanes mapping. What we use
// here instead in addition is the number of all lanes (not only the lanes
// in a turn):
//
// -v-v v-v- straight follows
// | | | |
// <- v v -> keep straight here
// | |
// <-| |->
//
// A route from the top left to the bottom right here goes over a keep
// straight. If we handle all keep straights as right turns (in right-sided
// driving), we wrongly guide the user to the rightmost lanes in the first turn.
// Not only is this wrong but the opposite of what we expect.
//
// The following implements a heuristic to determine a keep straight's
// direction in relation to the next step. In the above example we would get:
//
// coming from right, going to left (in direction of way) -> handle as left turn
if (previous_inst.type == TurnType::Suppressed &&
current_inst.type == TurnType::Suppressed && previous.mode == current.mode &&
previous_lanes == current_lanes)
{
previous.ElongateBy(current);
current.Invalidate();
}
});
if (is_straight_left.count(&current) > 0)
anticipate_for_left_turn();
else if (is_straight_right.count(&current) > 0)
anticipate_for_right_turn();
else // FIXME: right-sided driving
anticipate_for_right_turn();
}
if (previous_inst.type == TurnType::Suppressed &&
current_inst.type == TurnType::Suppressed && previous.mode == current.mode &&
previous_lanes == current_lanes)
{
previous.ElongateBy(current);
current.Invalidate();
}
});
};
std::for_each(begin(quick_lanes_ranges), end(quick_lanes_ranges), constrain_lanes);

Some files were not shown because too many files have changed in this diff Show More