Merge branch 'master' into sf-re-use-heap-in-getNetworkDistance

This commit is contained in:
Siarhei Fedartsou 2024-06-10 22:41:39 +02:00
commit 88708eedb0
330 changed files with 15173 additions and 20529 deletions

View File

@ -13,6 +13,10 @@ Checks: >
-bugprone-forward-declaration-namespace, -bugprone-forward-declaration-namespace,
-bugprone-sizeof-expression, -bugprone-sizeof-expression,
-bugprone-throw-keyword-missing, -bugprone-throw-keyword-missing,
-bugprone-chained-comparison,
-bugprone-incorrect-enable-if,
-bugprone-switch-missing-default-case,
-bugprone-empty-catch,
-clang-analyzer-*, -clang-analyzer-*,
-clang-diagnostic-deprecated-declarations, -clang-diagnostic-deprecated-declarations,
-clang-diagnostic-constant-conversion, -clang-diagnostic-constant-conversion,
@ -49,12 +53,13 @@ Checks: >
-misc-misplaced-const, -misc-misplaced-const,
-misc-definitions-in-headers, -misc-definitions-in-headers,
-misc-unused-parameters, -misc-unused-parameters,
-misc-include-cleaner,
modernize-concat-nested-namespaces, modernize-concat-nested-namespaces,
modernize-use-using, modernize-use-using,
performance-*, performance-*,
-performance-noexcept-move-constructor,
-performance-no-int-to-ptr, -performance-no-int-to-ptr,
-performance-type-promotion-in-math-fn, -performance-enum-size,
-performance-avoid-endl,
readability-*, readability-*,
-readability-avoid-const-params-in-decls, -readability-avoid-const-params-in-decls,
-readability-braces-around-statements, -readability-braces-around-statements,
@ -83,7 +88,10 @@ Checks: >
-readability-make-member-function-const, -readability-make-member-function-const,
-readability-redundant-string-init, -readability-redundant-string-init,
-readability-non-const-parameter, -readability-non-const-parameter,
-readability-container-contains, -readability-redundant-inline-specifier,
-readability-avoid-nested-conditional-operator,
-readability-avoid-return-with-void-value,
-readability-redundant-casting,
-readability-static-accessed-through-instance -readability-static-accessed-through-instance
WarningsAsErrors: '*' WarningsAsErrors: '*'

View File

@ -15,7 +15,6 @@ env:
CCACHE_TEMPDIR: /tmp/.ccache-temp CCACHE_TEMPDIR: /tmp/.ccache-temp
CCACHE_COMPRESS: 1 CCACHE_COMPRESS: 1
CASHER_TIME_OUT: 599 # one second less than 10m to avoid 10m timeout error: https://github.com/Project-OSRM/osrm-backend/issues/2742 CASHER_TIME_OUT: 599 # one second less than 10m to avoid 10m timeout error: https://github.com/Project-OSRM/osrm-backend/issues/2742
CCACHE_VERSION: 3.3.1
CMAKE_VERSION: 3.21.2 CMAKE_VERSION: 3.21.2
ENABLE_NODE_BINDINGS: "ON" ENABLE_NODE_BINDINGS: "ON"
@ -47,15 +46,32 @@ jobs:
echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV
- run: npm install --ignore-scripts - run: npm install --ignore-scripts
- run: npm link --ignore-scripts - run: npm link --ignore-scripts
- uses: microsoft/setup-msbuild@v2
- name: Build - name: Build
run: |
.\scripts\ci\windows-build.bat
- name: Run node tests
shell: bash shell: bash
run: | run: |
./lib/binding/osrm-datastore.exe test/data/ch/monaco.osrm mkdir build
node test/nodejs/index.js cd build
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_CONAN=ON -DENABLE_NODE_BINDINGS=ON ..
cmake --build . --config Release
# TODO: MSVC goes out of memory when building our tests
# - name: Run tests
# shell: bash
# run: |
# cd build
# cmake --build . --config Release --target tests
# # TODO: run tests
# - name: Run node tests
# shell: bash
# run: |
# ./lib/binding/osrm-extract.exe -p profiles/car.lua test/data/monaco.osm.pbf
# mkdir -p test/data/ch
# cp test/data/monaco.osrm* test/data/ch/
# ./lib/binding/osrm-contract.exe test/data/ch/monaco.osrm
# ./lib/binding/osrm-datastore.exe test/data/ch/monaco.osrm
# node test/nodejs/index.js
- name: Build Node package - name: Build Node package
shell: bash shell: bash
run: ./scripts/ci/node_package.sh run: ./scripts/ci/node_package.sh
@ -193,17 +209,18 @@ jobs:
CXXCOMPILER: clang++-15 CXXCOMPILER: clang++-15
CUCUMBER_TIMEOUT: 60000 CUCUMBER_TIMEOUT: 60000
- name: clang-15-debug-clang-tidy - name: clang-18-debug-clang-tidy
continue-on-error: false continue-on-error: false
node: 18 node: 18
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
BUILD_TOOLS: ON BUILD_TOOLS: ON
BUILD_TYPE: Debug BUILD_TYPE: Debug
CCOMPILER: clang-15 CCOMPILER: clang-18
CXXCOMPILER: clang++-15 CXXCOMPILER: clang++-18
CUCUMBER_TIMEOUT: 60000 CUCUMBER_TIMEOUT: 60000
ENABLE_CLANG_TIDY: ON ENABLE_CLANG_TIDY: ON
- name: clang-14-release - name: clang-14-release
continue-on-error: false continue-on-error: false
node: 18 node: 18
@ -245,6 +262,16 @@ jobs:
CXXCOMPILER: clang++-15 CXXCOMPILER: clang++-15
ENABLE_CONAN: ON ENABLE_CONAN: ON
- name: gcc-14-release
continue-on-error: false
node: 20
runs-on: ubuntu-24.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: gcc-14
CXXCOMPILER: g++-14
CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized'
- name: gcc-13-release - name: gcc-13-release
continue-on-error: false continue-on-error: false
node: 20 node: 20
@ -265,15 +292,6 @@ jobs:
CXXCOMPILER: g++-12 CXXCOMPILER: g++-12
CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized' CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized'
- name: gcc-11-release
continue-on-error: false
node: 20
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: gcc-11
CXXCOMPILER: g++-11
- name: conan-linux-release-node - name: conan-linux-release-node
build_node_package: true build_node_package: true
continue-on-error: false continue-on-error: false
@ -377,9 +395,11 @@ jobs:
key: v4-test-${{ matrix.name }}-${{ github.sha }} key: v4-test-${{ matrix.name }}-${{ github.sha }}
restore-keys: | restore-keys: |
v4-test-${{ matrix.name }}- v4-test-${{ matrix.name }}-
- name: Prepare environment - name: Prepare environment
run: | run: |
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
mkdir -p $HOME/.ccache
PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)") PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)")
echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV
echo "OSRM_INSTALL_DIR=${GITHUB_WORKSPACE}/install-osrm" >> $GITHUB_ENV echo "OSRM_INSTALL_DIR=${GITHUB_WORKSPACE}/install-osrm" >> $GITHUB_ENV
@ -456,7 +476,7 @@ jobs:
fi fi
# TBB # TBB
TBB_VERSION=2021.3.0 TBB_VERSION=2021.12.0
if [[ "${RUNNER_OS}" == "Linux" ]]; then if [[ "${RUNNER_OS}" == "Linux" ]]; then
TBB_URL="https://github.com/oneapi-src/oneTBB/releases/download/v${TBB_VERSION}/oneapi-tbb-${TBB_VERSION}-lin.tgz" TBB_URL="https://github.com/oneapi-src/oneTBB/releases/download/v${TBB_VERSION}/oneapi-tbb-${TBB_VERSION}-lin.tgz"
elif [[ "${RUNNER_OS}" == "macOS" ]]; then elif [[ "${RUNNER_OS}" == "macOS" ]]; then
@ -487,8 +507,8 @@ jobs:
run: | run: |
echo "Using ${JOBS} jobs" echo "Using ${JOBS} jobs"
pushd ${OSRM_BUILD_DIR} pushd ${OSRM_BUILD_DIR}
ccache --zero-stats
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_CONAN=${ENABLE_CONAN:-OFF} \ -DENABLE_CONAN=${ENABLE_CONAN:-OFF} \
-DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS:-OFF} \ -DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS:-OFF} \
@ -505,7 +525,7 @@ jobs:
if [[ "${NODE_PACKAGE_TESTS_ONLY}" != "ON" ]]; then if [[ "${NODE_PACKAGE_TESTS_ONLY}" != "ON" ]]; then
make tests --jobs=${JOBS} make tests --jobs=${JOBS}
make benchmarks --jobs=${JOBS} make benchmarks --jobs=${JOBS}
ccache -s
sudo make install sudo make install
if [[ "${RUNNER_OS}" == "Linux" ]]; then if [[ "${RUNNER_OS}" == "Linux" ]]; then
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${OSRM_INSTALL_DIR}/lib" >> $GITHUB_ENV echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${OSRM_INSTALL_DIR}/lib" >> $GITHUB_ENV
@ -608,7 +628,10 @@ jobs:
omitNameDuringUpdate: true omitNameDuringUpdate: true
replacesArtifacts: true replacesArtifacts: true
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
- name: Show CCache statistics
run: |
ccache -p
ccache -s
benchmarks: benchmarks:
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request'
@ -622,7 +645,16 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }} PR_NUMBER: ${{ github.event.pull_request.number }}
GITHUB_REPOSITORY: ${{ github.repository }} GITHUB_REPOSITORY: ${{ github.repository }}
RUN_BIG_BENCHMARK: ${{ contains(github.event.pull_request.labels.*.name, 'Performance') }}
steps: steps:
- name: Enable data.osm.pbf cache
if: ${{ ! env.RUN_BIG_BENCHMARK }}
uses: actions/cache@v4
with:
path: ~/data.osm.pbf
key: v1-data-osm-pbf
restore-keys: |
v1-data-osm-pbf
- name: Enable compiler cache - name: Enable compiler cache
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
@ -642,7 +674,30 @@ jobs:
with: with:
ref: ${{ github.head_ref }} ref: ${{ github.head_ref }}
path: pr path: pr
- run: python3 -m pip install "conan<2.0.0" "requests==2.31.0" - name: Install dependencies
run: |
python3 -m pip install "conan<2.0.0" "requests==2.31.0" "numpy==1.26.4"
sudo apt-get update -y && sudo apt-get install ccache
- name: Prepare data
run: |
if [ "$RUN_BIG_BENCHMARK" = "true" ]; then
rm -rf ~/data.osm.pbf
wget http://download.geofabrik.de/europe/poland-latest.osm.pbf -O ~/data.osm.pbf --quiet
gunzip -c ./pr/test/data/poland_gps_traces.csv.gz > ~/gps_traces.csv
else
if [ ! -f "~/data.osm.pbf" ]; then
wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf -O ~/data.osm.pbf
else
echo "Using cached data.osm.pbf"
fi
gunzip -c ./pr/test/data/berlin_gps_traces.csv.gz > ~/gps_traces.csv
fi
- name: Prepare environment
run: |
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
mkdir -p $HOME/.ccache
ccache --zero-stats
ccache --max-size=256M
- name: Build PR Branch - name: Build PR Branch
run: | run: |
mkdir -p pr/build mkdir -p pr/build
@ -672,6 +727,10 @@ jobs:
- name: Post Benchmark Results - name: Post Benchmark Results
run: | run: |
python3 pr/scripts/ci/post_benchmark_results.py base_results pr_results python3 pr/scripts/ci/post_benchmark_results.py base_results pr_results
- name: Show CCache statistics
run: |
ccache -p
ccache -s
ci-complete: ci-complete:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04

View File

@ -1,12 +1,15 @@
# Unreleased # Unreleased
- Changes from 5.27.1 - Changes from 5.27.1
- Features - Features
- REMOVED: Remove all core-CH left-overs [#6920](https://github.com/Project-OSRM/osrm-backend/pull/6920)
- ADDED: Add support for a keepalive_timeout flag. [#6674](https://github.com/Project-OSRM/osrm-backend/pull/6674) - ADDED: Add support for a keepalive_timeout flag. [#6674](https://github.com/Project-OSRM/osrm-backend/pull/6674)
- ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575) - ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575)
- ADDED: Add support for disabling feature datasets. [#6666](https://github.com/Project-OSRM/osrm-backend/pull/6666) - ADDED: Add support for disabling feature datasets. [#6666](https://github.com/Project-OSRM/osrm-backend/pull/6666)
- ADDED: Add support for opposite approach request parameter. [#6842](https://github.com/Project-OSRM/osrm-backend/pull/6842) - ADDED: Add support for opposite approach request parameter. [#6842](https://github.com/Project-OSRM/osrm-backend/pull/6842)
- ADDED: Add support for accessing edge flags in `process_segment` [#6658](https://github.com/Project-OSRM/osrm-backend/pull/6658) - ADDED: Add support for accessing edge flags in `process_segment` [#6658](https://github.com/Project-OSRM/osrm-backend/pull/6658)
- Build: - Build:
- CHANGED: Upgrade clang-format to version 15. [#6919](https://github.com/Project-OSRM/osrm-backend/pull/6919)
- CHANGED: Use Debian Bookworm as base Docker image [#6904](https://github.com/Project-OSRM/osrm-backend/pull/6904)
- CHANGED: Upgrade CI actions to latest versions [#6893](https://github.com/Project-OSRM/osrm-backend/pull/6893) - CHANGED: Upgrade CI actions to latest versions [#6893](https://github.com/Project-OSRM/osrm-backend/pull/6893)
- CHANGED: Remove outdated warnings #6894 [#6894](https://github.com/Project-OSRM/osrm-backend/pull/6894) - CHANGED: Remove outdated warnings #6894 [#6894](https://github.com/Project-OSRM/osrm-backend/pull/6894)
- ADDED: Add CI job which builds OSRM with gcc 12. [#6455](https://github.com/Project-OSRM/osrm-backend/pull/6455) - ADDED: Add CI job which builds OSRM with gcc 12. [#6455](https://github.com/Project-OSRM/osrm-backend/pull/6455)
@ -21,6 +24,15 @@
- NodeJS: - NodeJS:
- CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452) - CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452)
- Misc: - Misc:
- FIXED: Fix bugprone-unused-return-value clang-tidy warning. [#6934](https://github.com/Project-OSRM/osrm-backend/pull/6934)
- FIXED: Fix performance-noexcept-move-constructor clang-tidy warning. [#6931](https://github.com/Project-OSRM/osrm-backend/pull/6933)
- FIXED: Fix performance-noexcept-swap clang-tidy warning. [#6931](https://github.com/Project-OSRM/osrm-backend/pull/6931)
- CHANGED: Use custom struct instead of std::pair in QueryHeap. [#6921](https://github.com/Project-OSRM/osrm-backend/pull/6921)
- CHANGED: Use std::string_view::starts_with instead of boost::starts_with. [#6918](https://github.com/Project-OSRM/osrm-backend/pull/6918)
- CHANGED: Get rid of boost::math::constants::* and M_PI in favor of std::numbers. [#6916](https://github.com/Project-OSRM/osrm-backend/pull/6916)
- CHANGED: Make constants in PackedVector constexpr. [#6917](https://github.com/Project-OSRM/osrm-backend/pull/6917)
- CHANGED: Use std::variant instead of mapbox::util::variant. [#6903](https://github.com/Project-OSRM/osrm-backend/pull/6903)
- CHANGED: Bump rapidjson to version f9d53419e912910fd8fa57d5705fa41425428c35 [#6906](https://github.com/Project-OSRM/osrm-backend/pull/6906)
- CHANGED: Bump mapbox/variant to version 1.2.0 [#6898](https://github.com/Project-OSRM/osrm-backend/pull/6898) - CHANGED: Bump mapbox/variant to version 1.2.0 [#6898](https://github.com/Project-OSRM/osrm-backend/pull/6898)
- CHANGED: Avoid copy of std::function-based callback in path unpacking [#6895](https://github.com/Project-OSRM/osrm-backend/pull/6895) - CHANGED: Avoid copy of std::function-based callback in path unpacking [#6895](https://github.com/Project-OSRM/osrm-backend/pull/6895)
- CHANGED: Replace boost::hash by std::hash [#6892](https://github.com/Project-OSRM/osrm-backend/pull/6892) - CHANGED: Replace boost::hash by std::hash [#6892](https://github.com/Project-OSRM/osrm-backend/pull/6892)

View File

@ -120,8 +120,7 @@ endif()
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/) include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/)
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sol2-3.3.0/include) include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sol2/include)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/variant/include)
set(BOOST_COMPONENTS date_time chrono filesystem iostreams program_options regex system thread unit_test_framework) set(BOOST_COMPONENTS date_time chrono filesystem iostreams program_options regex system thread unit_test_framework)
@ -267,7 +266,6 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_dependency_defines(-DBOOST_LIB_DIAGNOSTIC) add_dependency_defines(-DBOOST_LIB_DIAGNOSTIC)
add_dependency_defines(-D_CRT_SECURE_NO_WARNINGS) add_dependency_defines(-D_CRT_SECURE_NO_WARNINGS)
add_dependency_defines(-DNOMINMAX) # avoid min and max macros that can break compilation add_dependency_defines(-DNOMINMAX) # avoid min and max macros that can break compilation
add_dependency_defines(-D_USE_MATH_DEFINES) #needed for M_PI with cmath.h
add_dependency_defines(-D_WIN32_WINNT=0x0501) add_dependency_defines(-D_WIN32_WINNT=0x0501)
add_dependency_defines(-DXML_STATIC) add_dependency_defines(-DXML_STATIC)
find_library(ws2_32_LIBRARY_PATH ws2_32) find_library(ws2_32_LIBRARY_PATH ws2_32)
@ -607,7 +605,6 @@ if (BUILD_ROUTED)
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE) set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
endif() endif()
file(GLOB VariantGlob third_party/variant/include/mapbox/*.hpp)
file(GLOB FlatbuffersGlob third_party/flatbuffers/include/flatbuffers/*.h) file(GLOB FlatbuffersGlob third_party/flatbuffers/include/flatbuffers/*.h)
file(GLOB LibraryGlob include/osrm/*.hpp) file(GLOB LibraryGlob include/osrm/*.hpp)
file(GLOB ParametersGlob include/engine/api/*_parameters.hpp) file(GLOB ParametersGlob include/engine/api/*_parameters.hpp)
@ -627,7 +624,6 @@ install(FILES ${ContractorHeader} DESTINATION include/osrm/contractor)
install(FILES ${LibraryGlob} DESTINATION include/osrm) install(FILES ${LibraryGlob} DESTINATION include/osrm)
install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api) install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api)
install(FILES ${ApiHeader} DESTINATION include/osrm/engine/api) install(FILES ${ApiHeader} DESTINATION include/osrm/engine/api)
install(FILES ${VariantGlob} DESTINATION include/mapbox)
install(FILES ${FlatbuffersGlob} DESTINATION include/flatbuffers) install(FILES ${FlatbuffersGlob} DESTINATION include/flatbuffers)
install(TARGETS osrm-extract DESTINATION bin) install(TARGETS osrm-extract DESTINATION bin)
install(TARGETS osrm-partition DESTINATION bin) install(TARGETS osrm-partition DESTINATION bin)

View File

@ -55,7 +55,7 @@ function(_get_msvc_ide_version result)
set(${result} 15 PARENT_SCOPE) set(${result} 15 PARENT_SCOPE)
elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930) elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930)
set(${result} 16 PARENT_SCOPE) set(${result} 16 PARENT_SCOPE)
elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1940) elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1950)
set(${result} 17 PARENT_SCOPE) set(${result} 17 PARENT_SCOPE)
else() else()
message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]") message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]")

View File

@ -1,15 +1,15 @@
FROM debian:bullseye-slim as builder FROM debian:bookworm-slim as builder
ARG DOCKER_TAG ARG DOCKER_TAG
ARG BUILD_CONCURRENCY ARG BUILD_CONCURRENCY
RUN mkdir -p /src && mkdir -p /opt RUN mkdir -p /src && mkdir -p /opt
RUN apt-get update && \ RUN apt-get update && \
apt-get -y --no-install-recommends install ca-certificates cmake make git gcc g++ libbz2-dev libxml2-dev wget \ apt-get -y --no-install-recommends install ca-certificates cmake make git gcc g++ libbz2-dev libxml2-dev wget \
libzip-dev libboost1.74-all-dev lua5.4 liblua5.4-dev pkg-config -o APT::Install-Suggests=0 -o APT::Install-Recommends=0 libzip-dev libboost1.81-all-dev lua5.4 liblua5.4-dev pkg-config -o APT::Install-Suggests=0 -o APT::Install-Recommends=0
RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \ RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
ldconfig /usr/local/lib && \ ldconfig /usr/local/lib && \
git clone --branch v2021.3.0 --single-branch https://github.com/oneapi-src/oneTBB.git && \ git clone --branch v2021.12.0 --single-branch https://github.com/oneapi-src/oneTBB.git && \
cd oneTBB && \ cd oneTBB && \
mkdir build && \ mkdir build && \
cd build && \ cd build && \
@ -21,6 +21,7 @@ COPY . /src
WORKDIR /src WORKDIR /src
RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \ RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
export CXXFLAGS="-Wno-array-bounds -Wno-uninitialized" && \
echo "Building OSRM ${DOCKER_TAG}" && \ echo "Building OSRM ${DOCKER_TAG}" && \
git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \ git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \
echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \ echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \
@ -42,15 +43,15 @@ RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
# Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds # Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
# Only the content below ends up in the image, this helps remove /src from the image (which is large) # Only the content below ends up in the image, this helps remove /src from the image (which is large)
FROM debian:bullseye-slim as runstage FROM debian:bookworm-slim as runstage
COPY --from=builder /usr/local /usr/local COPY --from=builder /usr/local /usr/local
COPY --from=builder /opt /opt COPY --from=builder /opt /opt
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends libboost-program-options1.74.0 libboost-regex1.74.0 \ apt-get install -y --no-install-recommends libboost-program-options1.81.0 libboost-regex1.81.0 \
libboost-date-time1.74.0 libboost-chrono1.74.0 libboost-filesystem1.74.0 \ libboost-date-time1.81.0 libboost-chrono1.81.0 libboost-filesystem1.81.0 \
libboost-iostreams1.74.0 libboost-system1.74.0 libboost-thread1.74.0 \ libboost-iostreams1.81.0 libboost-system1.81.0 libboost-thread1.81.0 \
expat liblua5.4-0 && \ expat liblua5.4-0 && \
rm -rf /var/lib/apt/lists/* && \ rm -rf /var/lib/apt/lists/* && \
# add /usr/local/lib to ldconfig to allow loading libraries from there # add /usr/local/lib to ldconfig to allow loading libraries from there

View File

@ -21,7 +21,7 @@ var osrm = new OSRM('network.osrm');
**Parameters** **Parameters**
- `options` **([Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** Options for creating an OSRM object or string to the `.osrm` file. (optional, default `{shared_memory:true}`) - `options` **([Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** Options for creating an OSRM object or string to the `.osrm` file. (optional, default `{shared_memory:true}`)
- `options.algorithm` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The algorithm to use for routing. Can be 'CH', 'CoreCH' or 'MLD'. Default is 'CH'. - `options.algorithm` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The algorithm to use for routing. Can be 'CH', or 'MLD'. Default is 'CH'.
Make sure you prepared the dataset with the correct toolchain. Make sure you prepared the dataset with the correct toolchain.
- `options.shared_memory` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore. - `options.shared_memory` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore.
This requires you to run `osrm-datastore` prior to creating an `OSRM` object. This requires you to run `osrm-datastore` prior to creating an `OSRM` object.

View File

@ -57,15 +57,15 @@ int main(int argc, const char *argv[])
// Execute routing request, this does the heavy lifting // Execute routing request, this does the heavy lifting
const auto status = osrm.Route(params, result); const auto status = osrm.Route(params, result);
auto &json_result = result.get<json::Object>(); auto &json_result = std::get<json::Object>(result);
if (status == Status::Ok) if (status == Status::Ok)
{ {
auto &routes = json_result.values["routes"].get<json::Array>(); auto &routes = std::get<json::Array>(json_result.values["routes"]);
// Let's just use the first route // Let's just use the first route
auto &route = routes.values.at(0).get<json::Object>(); auto &route = std::get<json::Object>(routes.values.at(0));
const auto distance = route.values["distance"].get<json::Number>().value; const auto distance = std::get<json::Number>(route.values["distance"]).value;
const auto duration = route.values["duration"].get<json::Number>().value; const auto duration = std::get<json::Number>(route.values["duration"]).value;
// Warn users if extract does not contain the default coordinates from above // Warn users if extract does not contain the default coordinates from above
if (distance == 0 || duration == 0) if (distance == 0 || duration == 0)
@ -80,8 +80,8 @@ int main(int argc, const char *argv[])
} }
else if (status == Status::Error) else if (status == Status::Error)
{ {
const auto code = json_result.values["code"].get<json::String>().value; const auto code = std::get<json::String>(json_result.values["code"]).value;
const auto message = json_result.values["message"].get<json::String>().value; const auto message = std::get<json::String>(json_result.values["message"]).value;
std::cout << "Code: " << code << "\n"; std::cout << "Code: " << code << "\n";
std::cout << "Message: " << code << "\n"; std::cout << "Message: " << code << "\n";

View File

@ -2,7 +2,7 @@
#define ENGINE_API_BASE_RESULT_HPP #define ENGINE_API_BASE_RESULT_HPP
#include <flatbuffers/flatbuffers.h> #include <flatbuffers/flatbuffers.h>
#include <mapbox/variant.hpp> #include <variant>
#include <string> #include <string>
@ -10,8 +10,7 @@
namespace osrm::engine::api namespace osrm::engine::api
{ {
using ResultT = using ResultT = std::variant<util::json::Object, std::string, flatbuffers::FlatBufferBuilder>;
mapbox::util::variant<util::json::Object, std::string, flatbuffers::FlatBufferBuilder>;
} // namespace osrm::engine::api } // namespace osrm::engine::api
#endif #endif

View File

@ -41,7 +41,7 @@ inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection
return intersection.lanes.lanes_in_turn > 0; return intersection.lanes.lanes_in_turn > 0;
} }
util::json::Array coordinateToLonLat(const util::Coordinate &coordinate); util::json::Value coordinateToLonLat(const util::Coordinate &coordinate);
/** /**
* Ensures that a bearing value is a whole number, and clamped to the range 0-359 * Ensures that a bearing value is a whole number, and clamped to the range 0-359
@ -79,7 +79,7 @@ util::json::Object makeGeoJSONGeometry(ForwardIter begin, ForwardIter end)
coordinates.values.push_back(location); coordinates.values.push_back(location);
coordinates.values.push_back(location); coordinates.values.push_back(location);
} }
geojson.values["coordinates"] = std::move(coordinates); geojson.values["coordinates"] = util::json::Value{std::move(coordinates)};
return geojson; return geojson;
} }

View File

@ -30,14 +30,14 @@ class MatchAPI final : public RouteAPI
osrm::engine::api::ResultT &response) const osrm::engine::api::ResultT &response) const
{ {
BOOST_ASSERT(sub_matchings.size() == sub_routes.size()); BOOST_ASSERT(sub_matchings.size() == sub_routes.size());
if (response.is<flatbuffers::FlatBufferBuilder>()) if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
{ {
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>(); auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
MakeResponse(sub_matchings, sub_routes, fb_result); MakeResponse(sub_matchings, sub_routes, fb_result);
} }
else else
{ {
auto &json_result = response.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(response);
MakeResponse(sub_matchings, sub_routes, json_result); MakeResponse(sub_matchings, sub_routes, json_result);
} }
} }

View File

@ -29,14 +29,14 @@ class NearestAPI final : public BaseAPI
BOOST_ASSERT(phantom_nodes.size() == 1); BOOST_ASSERT(phantom_nodes.size() == 1);
BOOST_ASSERT(parameters.coordinates.size() == 1); BOOST_ASSERT(parameters.coordinates.size() == 1);
if (response.is<flatbuffers::FlatBufferBuilder>()) if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
{ {
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>(); auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
MakeResponse(phantom_nodes, fb_result); MakeResponse(phantom_nodes, fb_result);
} }
else else
{ {
auto &json_result = response.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(response);
MakeResponse(phantom_nodes, json_result); MakeResponse(phantom_nodes, json_result);
} }
} }

View File

@ -50,14 +50,14 @@ class RouteAPI : public BaseAPI
{ {
BOOST_ASSERT(!raw_routes.routes.empty()); BOOST_ASSERT(!raw_routes.routes.empty());
if (response.is<flatbuffers::FlatBufferBuilder>()) if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
{ {
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>(); auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
MakeResponse(raw_routes, waypoint_candidates, fb_result); MakeResponse(raw_routes, waypoint_candidates, fb_result);
} }
else else
{ {
auto &json_result = response.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(response);
MakeResponse(raw_routes, waypoint_candidates, json_result); MakeResponse(raw_routes, waypoint_candidates, json_result);
} }
} }
@ -158,8 +158,8 @@ class RouteAPI : public BaseAPI
} }
template <typename ForwardIter> template <typename ForwardIter>
mapbox::util::variant<flatbuffers::Offset<flatbuffers::String>, std::variant<flatbuffers::Offset<flatbuffers::String>,
flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>> flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>>
MakeGeometry(flatbuffers::FlatBufferBuilder &builder, ForwardIter begin, ForwardIter end) const MakeGeometry(flatbuffers::FlatBufferBuilder &builder, ForwardIter begin, ForwardIter end) const
{ {
if (parameters.geometries == RouteParameters::GeometriesType::Polyline) if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
@ -408,8 +408,8 @@ class RouteAPI : public BaseAPI
// Fill geometry // Fill geometry
auto overview = MakeOverview(leg_geometries); auto overview = MakeOverview(leg_geometries);
mapbox::util::variant<flatbuffers::Offset<flatbuffers::String>, std::variant<flatbuffers::Offset<flatbuffers::String>,
flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>> flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>>
geometry; geometry;
if (overview) if (overview)
{ {
@ -426,8 +426,7 @@ class RouteAPI : public BaseAPI
routeObject.add_legs(legs_vector); routeObject.add_legs(legs_vector);
if (overview) if (overview)
{ {
mapbox::util::apply_visitor(GeometryVisitor<fbresult::RouteObjectBuilder>(routeObject), std::visit(GeometryVisitor<fbresult::RouteObjectBuilder>(routeObject), geometry);
geometry);
} }
return routeObject.Finish(); return routeObject.Finish();
@ -443,23 +442,22 @@ class RouteAPI : public BaseAPI
if (requested_annotations & RouteParameters::AnnotationsType::Speed) if (requested_annotations & RouteParameters::AnnotationsType::Speed)
{ {
double prev_speed = 0; double prev_speed = 0;
speed = speed = GetAnnotations<float>(
GetAnnotations<float>(fb_result, fb_result,
leg_geometry, leg_geometry,
[&prev_speed](const guidance::LegGeometry::Annotation &anno) [&prev_speed](const guidance::LegGeometry::Annotation &anno)
{ {
if (anno.duration < std::numeric_limits<float>::min()) if (anno.duration < std::numeric_limits<float>::min())
{ {
return prev_speed; return prev_speed;
} }
else else
{ {
auto speed = auto speed = std::round(anno.distance / anno.duration * 10.) / 10.;
round(anno.distance / anno.duration * 10.) / 10.; prev_speed = speed;
prev_speed = speed; return util::json::clamp_float(speed);
return util::json::clamp_float(speed); }
} });
});
} }
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> duration; flatbuffers::Offset<flatbuffers::Vector<uint32_t>> duration;
@ -645,7 +643,7 @@ class RouteAPI : public BaseAPI
stepBuilder.add_rotary_pronunciation(rotary_pronunciation_string); stepBuilder.add_rotary_pronunciation(rotary_pronunciation_string);
stepBuilder.add_intersections(intersections_vector); stepBuilder.add_intersections(intersections_vector);
stepBuilder.add_maneuver(maneuver_buffer); stepBuilder.add_maneuver(maneuver_buffer);
mapbox::util::apply_visitor(GeometryVisitor<fbresult::StepBuilder>(stepBuilder), geometry); std::visit(GeometryVisitor<fbresult::StepBuilder>(stepBuilder), geometry);
return stepBuilder.Finish(); return stepBuilder.Finish();
}; };

View File

@ -50,14 +50,14 @@ class TableAPI final : public BaseAPI
const std::vector<TableCellRef> &fallback_speed_cells, const std::vector<TableCellRef> &fallback_speed_cells,
osrm::engine::api::ResultT &response) const osrm::engine::api::ResultT &response) const
{ {
if (response.is<flatbuffers::FlatBufferBuilder>()) if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
{ {
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>(); auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
MakeResponse(tables, candidates, fallback_speed_cells, fb_result); MakeResponse(tables, candidates, fallback_speed_cells, fb_result);
} }
else else
{ {
auto &json_result = response.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(response);
MakeResponse(tables, candidates, fallback_speed_cells, json_result); MakeResponse(tables, candidates, fallback_speed_cells, json_result);
} }
} }
@ -377,7 +377,8 @@ class TableAPI final : public BaseAPI
return util::json::Value( return util::json::Value(
util::json::Number(from_alias<double>(duration) / 10.)); util::json::Number(from_alias<double>(duration) / 10.));
}); });
json_table.values.push_back(std::move(json_row));
json_table.values.push_back(util::json::Value{json_row});
} }
return json_table; return json_table;
} }
@ -406,7 +407,7 @@ class TableAPI final : public BaseAPI
return util::json::Value(util::json::Number( return util::json::Value(util::json::Number(
std::round(from_alias<double>(distance) * 10) / 10.)); std::round(from_alias<double>(distance) * 10) / 10.));
}); });
json_table.values.push_back(std::move(json_row)); json_table.values.push_back(util::json::Value{json_row});
} }
return json_table; return json_table;
} }
@ -415,15 +416,18 @@ class TableAPI final : public BaseAPI
MakeEstimatesTable(const std::vector<TableCellRef> &fallback_speed_cells) const MakeEstimatesTable(const std::vector<TableCellRef> &fallback_speed_cells) const
{ {
util::json::Array json_table; util::json::Array json_table;
std::for_each(fallback_speed_cells.begin(), std::for_each(
fallback_speed_cells.end(), fallback_speed_cells.begin(),
[&](const auto &cell) fallback_speed_cells.end(),
{ [&](const auto &cell)
util::json::Array row; {
row.values.push_back(util::json::Number(cell.row)); util::json::Array row;
row.values.push_back(util::json::Number(cell.column)); util::json::Value jCellRow{util::json::Number(static_cast<double>(cell.row))};
json_table.values.push_back(std::move(row)); util::json::Value jCellColumn{util::json::Number(static_cast<double>(cell.column))};
}); row.values.push_back(jCellRow);
row.values.push_back(jCellColumn);
json_table.values.push_back(util::json::Value{row});
});
return json_table; return json_table;
} }

View File

@ -27,14 +27,14 @@ class TripAPI final : public RouteAPI
{ {
BOOST_ASSERT(sub_trips.size() == sub_routes.size()); BOOST_ASSERT(sub_trips.size() == sub_routes.size());
if (response.is<flatbuffers::FlatBufferBuilder>()) if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
{ {
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>(); auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
MakeResponse(sub_trips, sub_routes, candidates, fb_result); MakeResponse(sub_trips, sub_routes, candidates, fb_result);
} }
else else
{ {
auto &json_result = response.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(response);
MakeResponse(sub_trips, sub_routes, candidates, json_result); MakeResponse(sub_trips, sub_routes, candidates, json_result);
} }
} }

View File

@ -54,14 +54,10 @@ namespace osrm::engine
* *
* In addition, shared memory can be used for datasets loaded with osrm-datastore. * In addition, shared memory can be used for datasets loaded with osrm-datastore.
* *
* You can chose between three algorithms: * You can chose between two algorithms:
* - Algorithm::CH * - Algorithm::CH
* Contraction Hierarchies, extremely fast queries but slow pre-processing. The default right * Contraction Hierarchies, extremely fast queries but slow pre-processing. The default right
* now. * now.
* - Algorithm::CoreCH
* Deprecated, to be removed in v6.0
* Contraction Hierachies with partial contraction for faster pre-processing but slower
* queries.
* - Algorithm::MLD * - Algorithm::MLD
* Multi Level Dijkstra, moderately fast in both pre-processing and query. * Multi Level Dijkstra, moderately fast in both pre-processing and query.
* *
@ -74,7 +70,6 @@ struct EngineConfig final
enum class Algorithm enum class Algorithm
{ {
CH, CH,
CoreCH, // Deprecated, will be removed in v6.0
MLD MLD
}; };

View File

@ -6,7 +6,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <boost/math/constants/constants.hpp> #include <numbers>
namespace osrm::engine::map_matching namespace osrm::engine::map_matching
{ {
@ -21,10 +21,8 @@ struct NormalDistribution
// FIXME implement log-probability version since it's faster // FIXME implement log-probability version since it's faster
double Density(const double val) const double Density(const double val) const
{ {
using namespace boost::math::constants;
const double x = val - mean; const double x = val - mean;
return 1.0 / (std::sqrt(two_pi<double>()) * standard_deviation) * return 1.0 / (std::sqrt(2 * std::numbers::pi) * standard_deviation) *
std::exp(-x * x / (standard_deviation * standard_deviation)); std::exp(-x * x / (standard_deviation * standard_deviation));
} }

View File

@ -4,7 +4,7 @@
#include "util/integer_range.hpp" #include "util/integer_range.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/math/constants/constants.hpp> #include <numbers>
#include <cmath> #include <cmath>
@ -14,7 +14,7 @@
namespace osrm::engine::map_matching namespace osrm::engine::map_matching
{ {
static const double log_2_pi = std::log(2. * boost::math::constants::pi<double>()); static const double log_2_pi = std::log(2. * std::numbers::pi);
static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits<double>::infinity(); static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits<double>::infinity();
static const double MINIMAL_LOG_PROB = std::numeric_limits<double>::lowest(); static const double MINIMAL_LOG_PROB = std::numeric_limits<double>::lowest();
static const std::size_t INVALID_STATE = std::numeric_limits<std::size_t>::max(); static const std::size_t INVALID_STATE = std::numeric_limits<std::size_t>::max();

View File

@ -2,7 +2,7 @@
#define ENGINE_MAP_MATCHING_CONFIDENCE_HPP #define ENGINE_MAP_MATCHING_CONFIDENCE_HPP
#include "engine/map_matching/bayes_classifier.hpp" #include "engine/map_matching/bayes_classifier.hpp"
#include <boost/assert.hpp>
#include <cmath> #include <cmath>
namespace osrm::engine::map_matching namespace osrm::engine::map_matching

View File

@ -95,7 +95,7 @@ class BasePlugin
const std::string &message, const std::string &message,
osrm::engine::api::ResultT &result) const osrm::engine::api::ResultT &result) const
{ {
mapbox::util::apply_visitor(ErrorRenderer(code, message), result); std::visit(ErrorRenderer(code, message), result);
return Status::Error; return Status::Error;
} }

View File

@ -12,7 +12,6 @@ namespace osrm::engine
// Algorithm-dependent heaps // Algorithm-dependent heaps
// - CH algorithms use CH heaps // - CH algorithms use CH heaps
// - CoreCH algorithms use CH
// - MLD algorithms use MLD heaps // - MLD algorithms use MLD heaps
template <typename Algorithm> struct SearchEngineData template <typename Algorithm> struct SearchEngineData

View File

@ -7,8 +7,8 @@
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <mapbox/variant.hpp>
#include <utility> #include <utility>
#include <variant>
namespace osrm::extractor namespace osrm::extractor
{ {

View File

@ -11,7 +11,7 @@
#include "util/std_hash.hpp" #include "util/std_hash.hpp"
#include "util/vector_view.hpp" #include "util/vector_view.hpp"
#include <mapbox/variant.hpp> #include <variant>
#include <algorithm> #include <algorithm>

View File

@ -1,12 +1,10 @@
#ifndef RESTRICTION_HPP #ifndef RESTRICTION_HPP
#define RESTRICTION_HPP #define RESTRICTION_HPP
#include "turn_path.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/opening_hours.hpp" #include "util/opening_hours.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include "mapbox/variant.hpp"
#include "turn_path.hpp"
#include <limits> #include <limits>
namespace osrm::extractor namespace osrm::extractor

View File

@ -215,7 +215,6 @@ inline void read(storage::tar::FileReader &reader,
const std::string &name, const std::string &name,
detail::NameTableImpl<Ownership> &name_table) detail::NameTableImpl<Ownership> &name_table)
{ {
std::string buffer;
util::serialization::read(reader, name, name_table.indexed_data); util::serialization::read(reader, name, name_table.indexed_data);
} }
} // namespace osrm::extractor::serialization } // namespace osrm::extractor::serialization

View File

@ -17,18 +17,18 @@ struct TrafficSignals
inline bool HasSignal(NodeID from, NodeID to) const inline bool HasSignal(NodeID from, NodeID to) const
{ {
return bidirectional_nodes.count(to) > 0 || unidirectional_segments.count({from, to}) > 0; return bidirectional_nodes.contains(to) || unidirectional_segments.contains({from, to});
} }
void Compress(NodeID from, NodeID via, NodeID to) void Compress(NodeID from, NodeID via, NodeID to)
{ {
bidirectional_nodes.erase(via); bidirectional_nodes.erase(via);
if (unidirectional_segments.count({via, to})) if (unidirectional_segments.contains({via, to}))
{ {
unidirectional_segments.erase({via, to}); unidirectional_segments.erase({via, to});
unidirectional_segments.insert({from, to}); unidirectional_segments.insert({from, to});
} }
if (unidirectional_segments.count({via, from})) if (unidirectional_segments.contains({via, from}))
{ {
unidirectional_segments.erase({via, from}); unidirectional_segments.erase({via, from});
unidirectional_segments.insert({to, from}); unidirectional_segments.insert({to, from});

View File

@ -4,7 +4,7 @@
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <algorithm> #include <algorithm>
#include <mapbox/variant.hpp> #include <variant>
#include <vector> #include <vector>
namespace osrm::extractor namespace osrm::extractor
@ -61,50 +61,50 @@ struct InputViaWayPath
struct InputTurnPath struct InputTurnPath
{ {
mapbox::util::variant<InputViaNodePath, InputViaWayPath> node_or_way; std::variant<InputViaNodePath, InputViaWayPath> node_or_way;
TurnPathType Type() const TurnPathType Type() const
{ {
BOOST_ASSERT(node_or_way.which() < TurnPathType::NUM_TURN_PATH_TYPES); BOOST_ASSERT(node_or_way.index() < TurnPathType::NUM_TURN_PATH_TYPES);
return static_cast<TurnPathType>(node_or_way.which()); return static_cast<TurnPathType>(node_or_way.index());
} }
OSMWayID From() const OSMWayID From() const
{ {
return node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH return node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH
? mapbox::util::get<InputViaNodePath>(node_or_way).from ? std::get<InputViaNodePath>(node_or_way).from
: mapbox::util::get<InputViaWayPath>(node_or_way).from; : std::get<InputViaWayPath>(node_or_way).from;
} }
OSMWayID To() const OSMWayID To() const
{ {
return node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH return node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH
? mapbox::util::get<InputViaNodePath>(node_or_way).to ? std::get<InputViaNodePath>(node_or_way).to
: mapbox::util::get<InputViaWayPath>(node_or_way).to; : std::get<InputViaWayPath>(node_or_way).to;
} }
InputViaWayPath &AsViaWayPath() InputViaWayPath &AsViaWayPath()
{ {
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_WAY_TURN_PATH); BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_WAY_TURN_PATH);
return mapbox::util::get<InputViaWayPath>(node_or_way); return std::get<InputViaWayPath>(node_or_way);
} }
const InputViaWayPath &AsViaWayPath() const const InputViaWayPath &AsViaWayPath() const
{ {
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_WAY_TURN_PATH); BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_WAY_TURN_PATH);
return mapbox::util::get<InputViaWayPath>(node_or_way); return std::get<InputViaWayPath>(node_or_way);
} }
InputViaNodePath &AsViaNodePath() InputViaNodePath &AsViaNodePath()
{ {
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH); BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH);
return mapbox::util::get<InputViaNodePath>(node_or_way); return std::get<InputViaNodePath>(node_or_way);
} }
const InputViaNodePath &AsViaNodePath() const const InputViaNodePath &AsViaNodePath() const
{ {
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH); BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH);
return mapbox::util::get<InputViaNodePath>(node_or_way); return std::get<InputViaNodePath>(node_or_way);
} }
}; };
@ -175,63 +175,63 @@ struct ViaWayPath
// between node/way paths // between node/way paths
struct TurnPath struct TurnPath
{ {
mapbox::util::variant<ViaNodePath, ViaWayPath> node_or_way; std::variant<ViaNodePath, ViaWayPath> node_or_way;
NodeID To() const NodeID To() const
{ {
return node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH return node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH
? mapbox::util::get<ViaNodePath>(node_or_way).to ? std::get<ViaNodePath>(node_or_way).to
: mapbox::util::get<ViaWayPath>(node_or_way).to; : std::get<ViaWayPath>(node_or_way).to;
} }
NodeID From() const NodeID From() const
{ {
return node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH return node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH
? mapbox::util::get<ViaNodePath>(node_or_way).from ? std::get<ViaNodePath>(node_or_way).from
: mapbox::util::get<ViaWayPath>(node_or_way).from; : std::get<ViaWayPath>(node_or_way).from;
} }
NodeID FirstVia() const NodeID FirstVia() const
{ {
if (node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH) if (node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH)
{ {
return mapbox::util::get<ViaNodePath>(node_or_way).via; return std::get<ViaNodePath>(node_or_way).via;
} }
else else
{ {
BOOST_ASSERT(!mapbox::util::get<ViaWayPath>(node_or_way).via.empty()); BOOST_ASSERT(!std::get<ViaWayPath>(node_or_way).via.empty());
return mapbox::util::get<ViaWayPath>(node_or_way).via[0]; return std::get<ViaWayPath>(node_or_way).via[0];
} }
} }
ViaWayPath &AsViaWayPath() ViaWayPath &AsViaWayPath()
{ {
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_WAY_TURN_PATH); BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_WAY_TURN_PATH);
return mapbox::util::get<ViaWayPath>(node_or_way); return std::get<ViaWayPath>(node_or_way);
} }
const ViaWayPath &AsViaWayPath() const const ViaWayPath &AsViaWayPath() const
{ {
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_WAY_TURN_PATH); BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_WAY_TURN_PATH);
return mapbox::util::get<ViaWayPath>(node_or_way); return std::get<ViaWayPath>(node_or_way);
} }
ViaNodePath &AsViaNodePath() ViaNodePath &AsViaNodePath()
{ {
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH); BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH);
return mapbox::util::get<ViaNodePath>(node_or_way); return std::get<ViaNodePath>(node_or_way);
} }
const ViaNodePath &AsViaNodePath() const const ViaNodePath &AsViaNodePath() const
{ {
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH); BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH);
return mapbox::util::get<ViaNodePath>(node_or_way); return std::get<ViaNodePath>(node_or_way);
} }
TurnPathType Type() const TurnPathType Type() const
{ {
BOOST_ASSERT(node_or_way.which() < TurnPathType::NUM_TURN_PATH_TYPES); BOOST_ASSERT(node_or_way.index() < TurnPathType::NUM_TURN_PATH_TYPES);
return static_cast<TurnPathType>(node_or_way.which()); return static_cast<TurnPathType>(node_or_way.index());
} }
bool operator==(const TurnPath &other) const bool operator==(const TurnPath &other) const

View File

@ -29,7 +29,7 @@ struct V8Renderer
for (const auto &keyValue : object.values) for (const auto &keyValue : object.values)
{ {
Napi::Value child; Napi::Value child;
mapbox::util::apply_visitor(V8Renderer(env, child), keyValue.second); std::visit(V8Renderer(env, child), keyValue.second);
obj.Set(keyValue.first, child); obj.Set(keyValue.first, child);
} }
out = obj; out = obj;
@ -41,7 +41,7 @@ struct V8Renderer
for (auto i = 0u; i < array.values.size(); ++i) for (auto i = 0u; i < array.values.size(); ++i)
{ {
Napi::Value child; Napi::Value child;
mapbox::util::apply_visitor(V8Renderer(env, child), array.values[i]); std::visit(V8Renderer(env, child), array.values[i]);
a.Set(i, child); a.Set(i, child);
} }
out = a; out = a;

View File

@ -28,6 +28,7 @@
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <variant>
#include <vector> #include <vector>
#include <exception> #include <exception>
@ -50,7 +51,7 @@ struct PluginParameters
bool renderToBuffer = false; bool renderToBuffer = false;
}; };
using ObjectOrString = typename mapbox::util::variant<osrm::json::Object, std::string>; using ObjectOrString = typename std::variant<osrm::json::Object, std::string>;
template <typename ResultT> inline Napi::Value render(const Napi::Env &env, const ResultT &result); template <typename ResultT> inline Napi::Value render(const Napi::Env &env, const ResultT &result);
@ -61,18 +62,18 @@ template <> Napi::Value inline render(const Napi::Env &env, const std::string &r
template <> Napi::Value inline render(const Napi::Env &env, const ObjectOrString &result) template <> Napi::Value inline render(const Napi::Env &env, const ObjectOrString &result)
{ {
if (result.is<osrm::json::Object>()) if (std::holds_alternative<osrm::json::Object>(result))
{ {
// Convert osrm::json object tree into matching v8 object tree // Convert osrm::json object tree into matching v8 object tree
Napi::Value value; Napi::Value value;
renderToV8(env, value, result.get<osrm::json::Object>()); renderToV8(env, value, std::get<osrm::json::Object>(result));
return value; return value;
} }
else else
{ {
// Return the string object as a node Buffer // Return the string object as a node Buffer
return Napi::Buffer<char>::Copy( return Napi::Buffer<char>::Copy(
env, result.get<std::string>().data(), result.get<std::string>().size()); env, std::get<std::string>(result).data(), std::get<std::string>(result).size());
} }
} }
@ -95,7 +96,7 @@ inline void ParseResult(const osrm::Status &result_status, osrm::json::Object &r
if (result_status == osrm::Status::Error) if (result_status == osrm::Status::Error)
{ {
throw std::logic_error(code_iter->second.get<osrm::json::String>().value.c_str()); throw std::logic_error(std::get<osrm::json::String>(code_iter->second).value.c_str());
} }
result.values.erase(code_iter); result.values.erase(code_iter);
@ -295,24 +296,19 @@ inline engine_config_ptr argumentsToEngineConfig(const Napi::CallbackInfo &args)
{ {
engine_config->algorithm = osrm::EngineConfig::Algorithm::CH; engine_config->algorithm = osrm::EngineConfig::Algorithm::CH;
} }
else if (algorithm_str == "CoreCH")
{
engine_config->algorithm = osrm::EngineConfig::Algorithm::CH;
}
else if (algorithm_str == "MLD") else if (algorithm_str == "MLD")
{ {
engine_config->algorithm = osrm::EngineConfig::Algorithm::MLD; engine_config->algorithm = osrm::EngineConfig::Algorithm::MLD;
} }
else else
{ {
ThrowError(args.Env(), "algorithm option must be one of 'CH', 'CoreCH', or 'MLD'."); ThrowError(args.Env(), "algorithm option must be one of 'CH', or 'MLD'.");
return engine_config_ptr(); return engine_config_ptr();
} }
} }
else if (!algorithm.IsUndefined()) else if (!algorithm.IsUndefined())
{ {
ThrowError(args.Env(), ThrowError(args.Env(), "algorithm option must be a string and one of 'CH', or 'MLD'.");
"algorithm option must be a string and one of 'CH', 'CoreCH', or 'MLD'.");
return engine_config_ptr(); return engine_config_ptr();
} }

View File

@ -12,7 +12,7 @@ struct header
// explicitly use default copy c'tor as adding move c'tor // explicitly use default copy c'tor as adding move c'tor
header &operator=(const header &other) = default; header &operator=(const header &other) = default;
header(std::string name, std::string value) : name(std::move(name)), value(std::move(value)) {} header(std::string name, std::string value) : name(std::move(name)), value(std::move(value)) {}
header(header &&other) : name(std::move(other.name)), value(std::move(other.value)) {} header(header &&other) noexcept : name(std::move(other.name)), value(std::move(other.value)) {}
void clear() void clear()
{ {

View File

@ -5,7 +5,7 @@
#include "osrm/osrm.hpp" #include "osrm/osrm.hpp"
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include <mapbox/variant.hpp> #include <variant>
#include <string> #include <string>
#include <vector> #include <vector>

View File

@ -61,7 +61,7 @@ class SharedMemory
{ {
shm = boost::interprocess::xsi_shared_memory(boost::interprocess::open_only, key); shm = boost::interprocess::xsi_shared_memory(boost::interprocess::open_only, key);
util::Log(logDEBUG) << "opening " << (int)shm.get_shmid() << " from id " << (int)id; util::Log(logDEBUG) << "opening " << shm.get_shmid() << " from id " << (int)id;
region = boost::interprocess::mapped_region(shm, boost::interprocess::read_only); region = boost::interprocess::mapped_region(shm, boost::interprocess::read_only);
} }

View File

@ -4,6 +4,7 @@
#include <cmath> #include <cmath>
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
#include <numbers>
#include <tuple> #include <tuple>
#include <utility> #include <utility>
@ -37,7 +38,7 @@ class CheapRuler
static constexpr double FE = 1.0 / 298.257223563; // flattening static constexpr double FE = 1.0 / 298.257223563; // flattening
static constexpr double E2 = FE * (2 - FE); static constexpr double E2 = FE * (2 - FE);
static constexpr double RAD = M_PI / 180.0; static constexpr double RAD = std::numbers::pi / 180.0;
public: public:
explicit CheapRuler(double latitude) explicit CheapRuler(double latitude)

View File

@ -26,7 +26,7 @@ struct ConcurrentIDMap
mutable UpgradableMutex mutex; mutable UpgradableMutex mutex;
ConcurrentIDMap() = default; ConcurrentIDMap() = default;
ConcurrentIDMap(ConcurrentIDMap &&other) ConcurrentIDMap(ConcurrentIDMap &&other) noexcept
{ {
if (this != &other) if (this != &other)
{ {
@ -36,7 +36,7 @@ struct ConcurrentIDMap
data = std::move(other.data); data = std::move(other.data);
} }
} }
ConcurrentIDMap &operator=(ConcurrentIDMap &&other) ConcurrentIDMap &operator=(ConcurrentIDMap &&other) noexcept
{ {
if (this != &other) if (this != &other)
{ {

View File

@ -3,7 +3,7 @@
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include <boost/math/constants/constants.hpp> #include <numbers>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
@ -23,17 +23,9 @@ const constexpr double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles) // The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
const constexpr long double EARTH_RADIUS = 6372797.560856; const constexpr long double EARTH_RADIUS = 6372797.560856;
inline double degToRad(const double degree) inline double degToRad(const double degree) { return degree * (std::numbers::pi / 180.0); }
{
using namespace boost::math::constants;
return degree * (pi<double>() / 180.0);
}
inline double radToDeg(const double radian) inline double radToDeg(const double radian) { return radian * (180.0 * std::numbers::inv_pi); }
{
using namespace boost::math::constants;
return radian * (180.0 * (1. / pi<double>()));
}
} // namespace detail } // namespace detail
const constexpr static double METERS_PER_DEGREE_LAT = 110567.0; const constexpr static double METERS_PER_DEGREE_LAT = 110567.0;

View File

@ -166,7 +166,7 @@ class DeallocatingVectorIterator
template <typename ElementT> class DeallocatingVector; template <typename ElementT> class DeallocatingVector;
template <typename T> void swap(DeallocatingVector<T> &lhs, DeallocatingVector<T> &rhs); template <typename T> void swap(DeallocatingVector<T> &lhs, DeallocatingVector<T> &rhs) noexcept;
template <typename ElementT> class DeallocatingVector template <typename ElementT> class DeallocatingVector
{ {
@ -204,8 +204,8 @@ template <typename ElementT> class DeallocatingVector
} }
// moving is fine // moving is fine
DeallocatingVector(DeallocatingVector &&other) { swap(other); } DeallocatingVector(DeallocatingVector &&other) noexcept { swap(other); }
DeallocatingVector &operator=(DeallocatingVector &&other) DeallocatingVector &operator=(DeallocatingVector &&other) noexcept
{ {
swap(other); swap(other);
return *this; return *this;
@ -221,9 +221,10 @@ template <typename ElementT> class DeallocatingVector
~DeallocatingVector() { clear(); } ~DeallocatingVector() { clear(); }
friend void swap<>(DeallocatingVector<ElementT> &lhs, DeallocatingVector<ElementT> &rhs); friend void swap<>(DeallocatingVector<ElementT> &lhs,
DeallocatingVector<ElementT> &rhs) noexcept;
void swap(DeallocatingVector<ElementT> &other) void swap(DeallocatingVector<ElementT> &other) noexcept
{ {
std::swap(current_size, other.current_size); std::swap(current_size, other.current_size);
bucket_list.swap(other.bucket_list); bucket_list.swap(other.bucket_list);
@ -342,7 +343,7 @@ template <typename ElementT> class DeallocatingVector
} }
}; };
template <typename T> void swap(DeallocatingVector<T> &lhs, DeallocatingVector<T> &rhs) template <typename T> void swap(DeallocatingVector<T> &lhs, DeallocatingVector<T> &rhs) noexcept
{ {
lhs.swap(rhs); lhs.swap(rhs);
} }

View File

@ -154,7 +154,7 @@ template <typename EdgeDataT> class DynamicGraph
return *this; return *this;
} }
DynamicGraph(DynamicGraph &&other) DynamicGraph(DynamicGraph &&other) noexcept
{ {
number_of_nodes = other.number_of_nodes; number_of_nodes = other.number_of_nodes;
// atomics can't be moved this is why we need an own constructor // atomics can't be moved this is why we need an own constructor
@ -164,7 +164,7 @@ template <typename EdgeDataT> class DynamicGraph
edge_list = std::move(other.edge_list); edge_list = std::move(other.edge_list);
} }
DynamicGraph &operator=(DynamicGraph &&other) DynamicGraph &operator=(DynamicGraph &&other) noexcept
{ {
number_of_nodes = other.number_of_nodes; number_of_nodes = other.number_of_nodes;
// atomics can't be moved this is why we need an own constructor // atomics can't be moved this is why we need an own constructor

View File

@ -51,7 +51,7 @@ class GeojsonLogger
if (!first) if (!first)
ofs << ",\n\t\t"; ofs << ",\n\t\t";
util::json::render(ofs, object.get<util::json::Object>()); util::json::render(ofs, std::get<util::json::Object>(object));
first = false; first = false;
} }

View File

@ -51,4 +51,4 @@ struct CoordinateVectorToMultiPoint
} // namespace osrm::util } // namespace osrm::util
#endif /* OSRM_GEOJSON_DEBUG_POLICIES */ #endif /* OSRM_GEOJSON_DEBUG_POLICIES */

View File

@ -55,12 +55,12 @@ inline util::json::Object makeStyle(const GeojsonStyleSize size_type,
struct CoordinateToJsonArray struct CoordinateToJsonArray
{ {
util::json::Array operator()(const util::Coordinate coordinate) util::json::Value operator()(const util::Coordinate coordinate)
{ {
util::json::Array json_coordinate; util::json::Array json_coordinate;
json_coordinate.values.push_back(static_cast<double>(toFloating(coordinate.lon))); json_coordinate.values.push_back(static_cast<double>(toFloating(coordinate.lon)));
json_coordinate.values.push_back(static_cast<double>(toFloating(coordinate.lat))); json_coordinate.values.push_back(static_cast<double>(toFloating(coordinate.lat)));
return json_coordinate; return util::json::Value{json_coordinate};
} }
}; };
@ -73,7 +73,7 @@ struct NodeIdToCoordinate
const std::vector<util::Coordinate> &node_coordinates; const std::vector<util::Coordinate> &node_coordinates;
util::json::Array operator()(const NodeID nid) util::json::Value operator()(const NodeID nid)
{ {
auto coordinate = node_coordinates[nid]; auto coordinate = node_coordinates[nid];
CoordinateToJsonArray converter; CoordinateToJsonArray converter;
@ -108,4 +108,4 @@ inline util::json::Array makeJsonArray(const std::vector<util::Coordinate> &inpu
} }
} // namespace osrm::util } // namespace osrm::util
#endif /* OSRM_GEOJSON_DEBUG_POLICY_TOOLKIT_HPP */ #endif /* OSRM_GEOJSON_DEBUG_POLICY_TOOLKIT_HPP */

View File

@ -8,8 +8,6 @@
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <boost/algorithm/string.hpp>
#include <algorithm> #include <algorithm>
#include <string> #include <string>
#include <tuple> #include <tuple>
@ -126,8 +124,7 @@ inline bool requiresNameAnnounced(const StringView &from_name,
// check similarity of names // check similarity of names
const auto names_are_empty = from_name.empty() && to_name.empty(); const auto names_are_empty = from_name.empty() && to_name.empty();
const auto name_is_contained = const auto name_is_contained = from_name.starts_with(to_name) || to_name.starts_with(from_name);
boost::starts_with(from_name, to_name) || boost::starts_with(to_name, from_name);
const auto checkForPrefixOrSuffixChange = [](const std::string_view first, const auto checkForPrefixOrSuffixChange = [](const std::string_view first,
const std::string_view second, const std::string_view second,

View File

@ -31,11 +31,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef JSON_CONTAINER_HPP #ifndef JSON_CONTAINER_HPP
#define JSON_CONTAINER_HPP #define JSON_CONTAINER_HPP
#include <mapbox/variant.hpp>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <utility> #include <utility>
#include <variant>
#include <vector> #include <vector>
namespace osrm::util::json namespace osrm::util::json
@ -96,13 +95,7 @@ struct Null
* *
* Dispatch on its type by either by using apply_visitor or its get function. * Dispatch on its type by either by using apply_visitor or its get function.
*/ */
using Value = mapbox::util::variant<String, using Value = std::variant<String, Number, Object, Array, True, False, Null>;
Number,
mapbox::util::recursive_wrapper<Object>,
mapbox::util::recursive_wrapper<Array>,
True,
False,
Null>;
/** /**
* Typed Object. * Typed Object.

View File

@ -81,10 +81,10 @@ struct Comparator
const auto &rhs_child = rhs.values.find(key)->second; const auto &rhs_child = rhs.values.find(key)->second;
const auto &lhs_child = lhs.values.find(key)->second; const auto &lhs_child = lhs.values.find(key)->second;
auto is_same = mapbox::util::apply_visitor( auto is_same =
Comparator(reason, lhs_path + "." + key, rhs_path + "." + key), std::visit(Comparator(reason, lhs_path + "." + key, rhs_path + "." + key),
lhs_child, lhs_child,
rhs_child); rhs_child);
if (!is_same) if (!is_same)
{ {
return false; return false;
@ -104,12 +104,11 @@ struct Comparator
for (auto i = 0UL; i < lhs.values.size(); ++i) for (auto i = 0UL; i < lhs.values.size(); ++i)
{ {
auto is_same = auto is_same = std::visit(Comparator(reason,
mapbox::util::apply_visitor(Comparator(reason, lhs_path + "[" + std::to_string(i) + "]",
lhs_path + "[" + std::to_string(i) + "]", rhs_path + "[" + std::to_string(i) + "]"),
rhs_path + "[" + std::to_string(i) + "]"), lhs.values[i],
lhs.values[i], rhs.values[i]);
rhs.values[i]);
if (!is_same) if (!is_same)
{ {
return false; return false;
@ -151,8 +150,7 @@ struct Comparator
inline bool compare(const Value &reference, const Value &result, std::string &reason) inline bool compare(const Value &reference, const Value &result, std::string &reason)
{ {
return mapbox::util::apply_visitor( return std::visit(Comparator(reason, "reference", "result"), reference, result);
Comparator(reason, "reference", "result"), reference, result);
} }
} // namespace osrm::util::json } // namespace osrm::util::json

View File

@ -67,7 +67,7 @@ template <typename Out> struct Renderer
write('\"'); write('\"');
write(it->first); write(it->first);
write<>("\":"); write<>("\":");
mapbox::util::apply_visitor(Renderer(out), it->second); std::visit(Renderer(out), it->second);
if (++it != end) if (++it != end)
{ {
write(','); write(',');
@ -81,7 +81,7 @@ template <typename Out> struct Renderer
write('['); write('[');
for (auto it = array.values.cbegin(), end = array.values.cend(); it != end;) for (auto it = array.values.cbegin(), end = array.values.cend(); it != end;)
{ {
mapbox::util::apply_visitor(Renderer(out), *it); std::visit(Renderer(out), *it);
if (++it != end) if (++it != end)
{ {
write(','); write(',');

View File

@ -1,49 +0,0 @@
#ifndef MATRIX_GRAPH_WRAPPER_H
#define MATRIX_GRAPH_WRAPPER_H
#include <cstddef>
#include <iterator>
#include <vector>
#include "util/typedefs.hpp"
namespace osrm::util
{
// This Wrapper provides all methods that are needed for util::TarjanSCC, when the graph is
// given in a matrix representation (e.g. as output from a distance table call)
template <typename T> class MatrixGraphWrapper
{
public:
MatrixGraphWrapper(std::vector<T> table, const std::size_t number_of_nodes)
: table_(std::move(table)), number_of_nodes_(number_of_nodes)
{
}
std::size_t GetNumberOfNodes() const { return number_of_nodes_; }
std::vector<T> GetAdjacentEdgeRange(const NodeID node) const
{
std::vector<T> edges;
// find all valid adjacent edges and move to vector `edges`
for (std::size_t i = 0; i < number_of_nodes_; ++i)
{
if (*(std::begin(table_) + node * number_of_nodes_ + i) != INVALID_EDGE_WEIGHT)
{
edges.push_back(i);
}
}
return edges;
}
EdgeWeight GetTarget(const EdgeWeight edge) const { return edge; }
private:
const std::vector<T> table_;
const std::size_t number_of_nodes_;
};
} // namespace osrm::util
#endif // MATRIX_GRAPH_WRAPPER_H

View File

@ -153,8 +153,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
// number of words per block // number of words per block
static constexpr std::size_t BLOCK_WORDS = (Bits * BLOCK_ELEMENTS) / WORD_BITS; static constexpr std::size_t BLOCK_WORDS = (Bits * BLOCK_ELEMENTS) / WORD_BITS;
// C++14 does not allow operator[] to be constexpr, this is fixed in C++17. static constexpr std::array<WordT, BLOCK_ELEMENTS> initialize_lower_mask()
static /* constexpr */ std::array<WordT, BLOCK_ELEMENTS> initialize_lower_mask()
{ {
std::array<WordT, BLOCK_ELEMENTS> lower_mask; std::array<WordT, BLOCK_ELEMENTS> lower_mask;
@ -170,7 +169,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
return lower_mask; return lower_mask;
} }
static /* constexpr */ std::array<WordT, BLOCK_ELEMENTS> initialize_upper_mask() static constexpr std::array<WordT, BLOCK_ELEMENTS> initialize_upper_mask()
{ {
std::array<WordT, BLOCK_ELEMENTS> upper_mask; std::array<WordT, BLOCK_ELEMENTS> upper_mask;
@ -194,7 +193,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
return upper_mask; return upper_mask;
} }
static /* constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_lower_offset() static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_lower_offset()
{ {
std::array<std::uint8_t, WORD_BITS> lower_offset; std::array<std::uint8_t, WORD_BITS> lower_offset;
@ -209,7 +208,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
return lower_offset; return lower_offset;
} }
static /* constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_upper_offset() static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_upper_offset()
{ {
std::array<std::uint8_t, BLOCK_ELEMENTS> upper_offset; std::array<std::uint8_t, BLOCK_ELEMENTS> upper_offset;
@ -232,7 +231,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
return upper_offset; return upper_offset;
} }
static /* constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_word_offset() static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_word_offset()
{ {
std::array<std::uint8_t, BLOCK_ELEMENTS> word_offset; std::array<std::uint8_t, BLOCK_ELEMENTS> word_offset;
@ -246,28 +245,15 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
return word_offset; return word_offset;
} }
// For now we need to call these on object creation
void initialize()
{
lower_mask = initialize_lower_mask();
upper_mask = initialize_upper_mask();
lower_offset = initialize_lower_offset();
upper_offset = initialize_upper_offset();
word_offset = initialize_word_offset();
}
// mask for the lower/upper word of a record // mask for the lower/upper word of a record
// TODO: With C++17 these could be constexpr static constexpr std::array<WordT, BLOCK_ELEMENTS> lower_mask = initialize_lower_mask();
/* static constexpr */ std::array<WordT, BLOCK_ELEMENTS> static constexpr std::array<WordT, BLOCK_ELEMENTS> upper_mask = initialize_upper_mask();
lower_mask /* = initialize_lower_mask()*/; static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> lower_offset =
/* static constexpr */ std::array<WordT, BLOCK_ELEMENTS> initialize_lower_offset();
upper_mask /* = initialize_upper_mask()*/; static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> upper_offset =
/* static constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS> initialize_upper_offset();
lower_offset /* = initialize_lower_offset()*/;
/* static constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS>
upper_offset /* = initialize_upper_offset()*/;
// in which word of the block is the element // in which word of the block is the element
/* static constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS> word_offset = static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> word_offset =
initialize_word_offset(); initialize_word_offset();
struct InternalIndex struct InternalIndex
@ -378,27 +364,21 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
PackedVector(std::initializer_list<T> list) PackedVector(std::initializer_list<T> list)
{ {
initialize();
reserve(list.size()); reserve(list.size());
for (const auto value : list) for (const auto value : list)
push_back(value); push_back(value);
} }
PackedVector() { initialize(); }; PackedVector(){};
PackedVector(const PackedVector &) = default; PackedVector(const PackedVector &) = default;
PackedVector(PackedVector &&) = default; PackedVector(PackedVector &&) = default;
PackedVector &operator=(const PackedVector &) = default; PackedVector &operator=(const PackedVector &) = default;
PackedVector &operator=(PackedVector &&) = default; PackedVector &operator=(PackedVector &&) = default;
PackedVector(std::size_t size) PackedVector(std::size_t size) { resize(size); }
{
initialize();
resize(size);
}
PackedVector(std::size_t size, T initial_value) PackedVector(std::size_t size, T initial_value)
{ {
initialize();
resize(size); resize(size);
fill(initial_value); fill(initial_value);
} }
@ -406,7 +386,6 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
PackedVector(util::ViewOrVector<WordT, Ownership> vec_, std::size_t num_elements) PackedVector(util::ViewOrVector<WordT, Ownership> vec_, std::size_t num_elements)
: vec(std::move(vec_)), num_elements(num_elements) : vec(std::move(vec_)), num_elements(num_elements)
{ {
initialize();
} }
// forces the efficient read-only lookup // forces the efficient read-only lookup

View File

@ -10,9 +10,9 @@ namespace osrm::util
namespace permutation_detail namespace permutation_detail
{ {
template <typename T> static inline void swap(T &a, T &b) { std::swap(a, b); } template <typename T> static inline void swap(T &a, T &b) noexcept { std::swap(a, b); }
static inline void swap(std::vector<bool>::reference a, std::vector<bool>::reference b) static inline void swap(std::vector<bool>::reference a, std::vector<bool>::reference b) noexcept
{ {
std::vector<bool>::swap(a, b); std::vector<bool>::swap(a, b);
} }

View File

@ -193,7 +193,20 @@ template <typename NodeID,
class QueryHeap class QueryHeap
{ {
private: private:
using HeapData = std::pair<Weight, Key>; struct HeapData
{
Weight weight;
Key index;
bool operator>(const HeapData &other) const
{
if (weight == other.weight)
{
return index > other.index;
}
return weight > other.weight;
}
};
using HeapContainer = boost::heap::d_ary_heap<HeapData, using HeapContainer = boost::heap::d_ary_heap<HeapData,
boost::heap::arity<4>, boost::heap::arity<4>,
boost::heap::mutable_<true>, boost::heap::mutable_<true>,
@ -232,7 +245,7 @@ class QueryHeap
{ {
BOOST_ASSERT(node < std::numeric_limits<NodeID>::max()); BOOST_ASSERT(node < std::numeric_limits<NodeID>::max());
const auto index = static_cast<Key>(inserted_nodes.size()); const auto index = static_cast<Key>(inserted_nodes.size());
const auto handle = heap.push(std::make_pair(weight, index)); const auto handle = heap.emplace(HeapData{weight, index});
inserted_nodes.emplace_back(HeapNode{handle, node, weight, data}); inserted_nodes.emplace_back(HeapNode{handle, node, weight, data});
node_index[node] = index; node_index[node] = index;
} }
@ -315,19 +328,19 @@ class QueryHeap
NodeID Min() const NodeID Min() const
{ {
BOOST_ASSERT(!heap.empty()); BOOST_ASSERT(!heap.empty());
return inserted_nodes[heap.top().second].node; return inserted_nodes[heap.top().index].node;
} }
Weight MinKey() const Weight MinKey() const
{ {
BOOST_ASSERT(!heap.empty()); BOOST_ASSERT(!heap.empty());
return heap.top().first; return heap.top().weight;
} }
NodeID DeleteMin() NodeID DeleteMin()
{ {
BOOST_ASSERT(!heap.empty()); BOOST_ASSERT(!heap.empty());
const Key removedIndex = heap.top().second; const Key removedIndex = heap.top().index;
heap.pop(); heap.pop();
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end()); inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
return inserted_nodes[removedIndex].node; return inserted_nodes[removedIndex].node;
@ -336,7 +349,7 @@ class QueryHeap
HeapNode &DeleteMinGetHeapNode() HeapNode &DeleteMinGetHeapNode()
{ {
BOOST_ASSERT(!heap.empty()); BOOST_ASSERT(!heap.empty());
const Key removedIndex = heap.top().second; const Key removedIndex = heap.top().index;
heap.pop(); heap.pop();
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end()); inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
return inserted_nodes[removedIndex]; return inserted_nodes[removedIndex];
@ -357,13 +370,13 @@ class QueryHeap
const auto index = node_index.peek_index(node); const auto index = node_index.peek_index(node);
auto &reference = inserted_nodes[index]; auto &reference = inserted_nodes[index];
reference.weight = weight; reference.weight = weight;
heap.increase(reference.handle, std::make_pair(weight, index)); heap.increase(reference.handle, HeapData{weight, static_cast<Key>(index)});
} }
void DecreaseKey(const HeapNode &heapNode) void DecreaseKey(const HeapNode &heapNode)
{ {
BOOST_ASSERT(!WasRemoved(heapNode.node)); BOOST_ASSERT(!WasRemoved(heapNode.node));
heap.increase(heapNode.handle, std::make_pair(heapNode.weight, (*heapNode.handle).second)); heap.increase(heapNode.handle, HeapData{heapNode.weight, (*heapNode.handle).index});
} }
private: private:

View File

@ -1,8 +1,9 @@
#ifndef STRING_UTIL_HPP #ifndef STRING_UTIL_HPP
#define STRING_UTIL_HPP #define STRING_UTIL_HPP
#include <array>
#include <cctype> #include <cctype>
#include <cstddef>
#include <random> #include <random>
#include <string> #include <string>
#include <vector> #include <vector>
@ -10,73 +11,30 @@
namespace osrm::util namespace osrm::util
{ {
// precision: position after decimal point // implements Lemire's table-based escape needs check
// length: maximum number of digits including comma and decimals // cf. https://lemire.me/blog/2024/05/31/quickly-checking-whether-a-string-needs-escaping/
// work with negative values to prevent overflowing when taking -value inline static constexpr std::array<uint8_t, 256> json_quotable_character = []() constexpr
template <int length, int precision> char *printInt(char *buffer, int value)
{ {
static_assert(length > 0, "length must be positive"); std::array<uint8_t, 256> result{};
static_assert(precision > 0, "precision must be positive"); for (auto i = 0; i < 32; i++)
const bool minus = [&value]
{ {
if (value >= 0) result[i] = 1;
{
value = -value;
return false;
}
return true;
}();
buffer += length - 1;
for (int i = 0; i < precision; ++i)
{
*buffer = '0' - (value % 10);
value /= 10;
--buffer;
} }
*buffer = '.'; for (auto i : {'"', '\\'})
--buffer;
for (int i = precision + 1; i < length; ++i)
{ {
*buffer = '0' - (value % 10); result[i] = 1;
value /= 10;
if (value == 0)
{
break;
}
--buffer;
} }
return result;
if (minus) }();
{
--buffer;
*buffer = '-';
}
return buffer;
}
inline bool RequiresJSONStringEscaping(const std::string &string) inline bool RequiresJSONStringEscaping(const std::string &string)
{ {
for (const char letter : string) uint8_t needs = 0;
for (uint8_t c : string)
{ {
switch (letter) needs |= json_quotable_character[c];
{
case '\\':
case '"':
case '/':
case '\b':
case '\f':
case '\n':
case '\r':
case '\t':
return true;
default:
continue;
}
} }
return false; return needs;
} }
inline void EscapeJSONString(const std::string &input, std::string &output) inline void EscapeJSONString(const std::string &input, std::string &output)

View File

@ -6,7 +6,7 @@
#include <limits> #include <limits>
#include <boost/math/constants/constants.hpp> #include <numbers>
namespace osrm::util namespace osrm::util
{ {
@ -356,25 +356,21 @@ constexpr unsigned short atan_table[4096] = {
0xffe0, 0xffea, 0xfff4, 0xffff}; 0xffe0, 0xffea, 0xfff4, 0xffff};
// max value is pi/4 // max value is pi/4
#ifdef _MSC_VER // TODO: remove as soon as boost allows C++14 features with Visual Studio const constexpr double SCALING_FACTOR = 4. * std::numbers::inv_pi * 0xFFFF;
const constexpr double SCALING_FACTOR = 4. / M_PI * 0xFFFF;
#else
const constexpr double SCALING_FACTOR = 4. / boost::math::constants::pi<double>() * 0xFFFF;
#endif
inline double atan2_lookup(double y, double x) inline double atan2_lookup(double y, double x)
{ {
using namespace boost::math::constants; static constexpr auto half_pi = std::numbers::pi * 0.5;
if (std::abs(x) < std::numeric_limits<double>::epsilon()) if (std::abs(x) < std::numeric_limits<double>::epsilon())
{ {
if (y >= 0.) if (y >= 0.)
{ {
return half_pi<double>(); return half_pi;
} }
else else
{ {
return -half_pi<double>(); return -half_pi;
} }
} }
@ -405,25 +401,25 @@ inline double atan2_lookup(double y, double x)
case 0: case 0:
break; break;
case 1: case 1:
angle = pi<double>() - angle; angle = std::numbers::pi - angle;
break; break;
case 2: case 2:
angle = -angle; angle = -angle;
break; break;
case 3: case 3:
angle = -pi<double>() + angle; angle = -std::numbers::pi + angle;
break; break;
case 4: case 4:
angle = half_pi<double>() - angle; angle = half_pi - angle;
break; break;
case 5: case 5:
angle = half_pi<double>() + angle; angle = half_pi + angle;
break; break;
case 6: case 6:
angle = -half_pi<double>() + angle; angle = -half_pi + angle;
break; break;
case 7: case 7:
angle = -half_pi<double>() - angle; angle = -half_pi - angle;
break; break;
} }
return angle; return angle;

View File

@ -3,7 +3,7 @@
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include <boost/math/constants/constants.hpp> #include <numbers>
namespace osrm::util::web_mercator namespace osrm::util::web_mercator
{ {
@ -14,7 +14,7 @@ const constexpr double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
// radius used by WGS84 // radius used by WGS84
const constexpr double EARTH_RADIUS_WGS84 = 6378137.0; const constexpr double EARTH_RADIUS_WGS84 = 6378137.0;
// earth circumference devided by 2 // earth circumference devided by 2
const constexpr double MAXEXTENT = EARTH_RADIUS_WGS84 * boost::math::constants::pi<double>(); const constexpr double MAXEXTENT = EARTH_RADIUS_WGS84 * std::numbers::pi;
// ^ math functions are not constexpr since they have side-effects (setting errno) :( // ^ math functions are not constexpr since they have side-effects (setting errno) :(
const constexpr double EPSG3857_MAX_LATITUDE = 85.051128779806592378; // 90(4*atan(exp(pi))/pi-1) const constexpr double EPSG3857_MAX_LATITUDE = 85.051128779806592378; // 90(4*atan(exp(pi))/pi-1)
const constexpr double MAX_LONGITUDE = 180.0; const constexpr double MAX_LONGITUDE = 180.0;
@ -103,8 +103,8 @@ inline void pixelToDegree(const double shift, double &x, double &y)
const double b = shift / 2.0; const double b = shift / 2.0;
x = (x - b) / shift * 360.0; x = (x - b) / shift * 360.0;
// FIXME needs to be simplified // FIXME needs to be simplified
const double g = (y - b) / -(shift / (2 * M_PI)) / detail::DEGREE_TO_RAD; const double g = (y - b) / -(shift * 0.5 * std::numbers::inv_pi) / detail::DEGREE_TO_RAD;
static_assert(detail::DEGREE_TO_RAD / (2 * M_PI) - 1 / 360. < 0.0001, ""); static_assert(detail::DEGREE_TO_RAD * 0.5 * std::numbers::inv_pi - 1 / 360. < 0.0001, "");
y = static_cast<double>(yToLat(g)); y = static_cast<double>(yToLat(g));
} }

View File

@ -0,0 +1,90 @@
import requests
import xml.etree.ElementTree as ET
import csv
import sys
import argparse
def get_osm_gps_traces(bboxes):
url = 'https://api.openstreetmap.org/api/0.6/trackpoints'
traces = []
lon_step = 0.25
lat_step = 0.25
for bbox in bboxes:
min_lon, min_lat, max_lon, max_lat = map(float, bbox.split(','))
current_min_lon = min_lon
while current_min_lon < max_lon:
current_max_lon = min(current_min_lon + lon_step, max_lon)
current_min_lat = min_lat
while current_min_lat < max_lat:
current_max_lat = min(current_min_lat + lat_step, max_lat)
bbox_str = f'{current_min_lon},{current_min_lat},{current_max_lon},{current_max_lat}'
print(f"Requesting bbox: {bbox_str}", file=sys.stderr)
params = {
'bbox': bbox_str,
'page': 0
}
headers = {
'Accept': 'application/xml'
}
response = requests.get(url, params=params, headers=headers)
if response.status_code == 200:
traces.append(response.content)
else:
print(f"Error fetching data for bbox {bbox_str}: {response.status_code} {response.text}", file=sys.stderr)
current_min_lat += lat_step
current_min_lon += lon_step
return traces
def parse_gpx_data(gpx_data):
try:
root = ET.fromstring(gpx_data)
except ET.ParseError as e:
print(f"Error parsing GPX data: {e}", file=sys.stderr)
return []
namespace = {'gpx': 'http://www.topografix.com/GPX/1/0'}
tracks = []
for trk in root.findall('.//gpx:trk', namespace):
track_data = []
for trkseg in trk.findall('.//gpx:trkseg', namespace):
for trkpt in trkseg.findall('gpx:trkpt', namespace):
lat = trkpt.get('lat')
lon = trkpt.get('lon')
time = trkpt.find('time').text if trkpt.find('time') is not None else ''
track_data.append([lat, lon, time])
tracks.append(track_data)
return tracks
def save_to_csv(data, file):
writer = csv.writer(file)
writer.writerow(['TrackID', 'Latitude', 'Longitude', 'Time'])
writer.writerows(data)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Fetch and output OSM GPS traces for given bounding boxes.')
parser.add_argument('bboxes', nargs='+', help='Bounding boxes in the format min_lon,min_lat,max_lon,max_lat')
args = parser.parse_args()
gpx_data_traces = get_osm_gps_traces(args.bboxes)
print(f"Collected {len(gpx_data_traces)} trace segments", file=sys.stderr)
all_data = []
track_id = 0
for gpx_data in gpx_data_traces:
for track in parse_gpx_data(gpx_data):
for point in track:
all_data.append([track_id] + point)
track_id += 1
# Output all data to stdout
save_to_csv(all_data, sys.stdout)

102
scripts/ci/e2e_benchmark.py Normal file
View File

@ -0,0 +1,102 @@
import requests
import sys
import random
from collections import defaultdict
import os
import csv
import numpy as np
import time
import argparse
class BenchmarkRunner:
def __init__(self):
self.coordinates = []
self.tracks = defaultdict(list)
gps_traces_file_path = os.path.expanduser('~/gps_traces.csv')
with open(gps_traces_file_path, 'r') as file:
reader = csv.DictReader(file)
for row in reader:
coord = (float(row['Latitude']), float(row['Longitude']))
self.coordinates.append(coord)
self.tracks[row['TrackID']].append(coord)
self.track_ids = list(self.tracks.keys())
def run(self, benchmark_name, host, num_requests, warmup_requests=50):
for _ in range(warmup_requests):
url = self.make_url(host, benchmark_name)
_ = requests.get(url)
times = []
for _ in range(num_requests):
url = self.make_url(host, benchmark_name)
start_time = time.time()
response = requests.get(url)
end_time = time.time()
if response.status_code != 200:
if benchmark_name == 'match':
code = response.json()['code']
if code == 'NoSegment' or code == 'NoMatch':
continue
raise Exception(f"Error: {response.status_code} {response.text}")
times.append((end_time - start_time) * 1000) # convert to ms
return times
def make_url(self, host, benchmark_name):
if benchmark_name == 'route':
start = random.choice(self.coordinates)
end = random.choice(self.coordinates)
start_coord = f"{start[1]:.6f},{start[0]:.6f}"
end_coord = f"{end[1]:.6f},{end[0]:.6f}"
return f"{host}/route/v1/driving/{start_coord};{end_coord}?overview=full&steps=true"
elif benchmark_name == 'table':
num_coords = random.randint(3, 100)
selected_coords = random.sample(self.coordinates, num_coords)
coords_str = ";".join([f"{coord[1]:.6f},{coord[0]:.6f}" for coord in selected_coords])
return f"{host}/table/v1/driving/{coords_str}"
elif benchmark_name == 'match':
num_coords = random.randint(50, 100)
track_id = random.choice(self.track_ids)
track_coords = self.tracks[track_id][:num_coords]
coords_str = ";".join([f"{coord[1]:.6f},{coord[0]:.6f}" for coord in track_coords])
radiues_str = ";".join([f"{random.randint(5, 20)}" for _ in range(len(track_coords))])
return f"{host}/match/v1/driving/{coords_str}?steps=true&radiuses={radiues_str}"
elif benchmark_name == 'nearest':
coord = random.choice(self.coordinates)
coord_str = f"{coord[1]:.6f},{coord[0]:.6f}"
return f"{host}/nearest/v1/driving/{coord_str}"
elif benchmark_name == 'trip':
num_coords = random.randint(2, 10)
selected_coords = random.sample(self.coordinates, num_coords)
coords_str = ";".join([f"{coord[1]:.6f},{coord[0]:.6f}" for coord in selected_coords])
return f"{host}/trip/v1/driving/{coords_str}?steps=true"
else:
raise Exception(f"Unknown benchmark: {benchmark_name}")
def main():
parser = argparse.ArgumentParser(description='Run GPS benchmark tests.')
parser.add_argument('--host', type=str, required=True, help='Host URL')
parser.add_argument('--method', type=str, required=True, choices=['route', 'table', 'match', 'nearest', 'trip'], help='Benchmark method')
parser.add_argument('--num_requests', type=int, required=True, help='Number of requests to perform')
args = parser.parse_args()
random.seed(42)
runner = BenchmarkRunner()
times = runner.run(args.method, args.host, args.num_requests)
print(f'Total: {np.sum(times)}ms')
print(f"Min time: {np.min(times)}ms")
print(f"Mean time: {np.mean(times)}ms")
print(f"Median time: {np.median(times)}ms")
print(f"95th percentile: {np.percentile(times, 95)}ms")
print(f"99th percentile: {np.percentile(times, 99)}ms")
print(f"Max time: {np.max(times)}ms")
if __name__ == '__main__':
main()

View File

@ -16,8 +16,10 @@ def create_markdown_table(results):
rows = [] rows = []
for result in results: for result in results:
name = result['name'] name = result['name']
base = result['base'].replace('\n', '<br/>') base = result['base'] or ''
pr = result['pr'].replace('\n', '<br/>') base = base.replace('\n', '<br/>')
pr = result['pr'] or ''
pr = pr.replace('\n', '<br/>')
row = f"| {name} | {base} | {pr} |" row = f"| {name} | {base} | {pr} |"
rows.append(row) rows.append(row)
return f"{header}\n" + "\n".join(rows) return f"{header}\n" + "\n".join(rows)
@ -75,7 +77,14 @@ def main():
pr_body = pr_details.get('body', '') or '' pr_body = pr_details.get('body', '') or ''
markdown_table = create_markdown_table(benchmark_results) markdown_table = create_markdown_table(benchmark_results)
new_benchmark_section = f"<!-- BENCHMARK_RESULTS_START -->\n## Benchmark Results\n{markdown_table}\n<!-- BENCHMARK_RESULTS_END -->" new_benchmark_section = f"""
<!-- BENCHMARK_RESULTS_START -->
<details><summary><h2>Benchmark Results</h2></summary>
{markdown_table}
</details>
<!-- BENCHMARK_RESULTS_END -->
"""
if re.search(r'<!-- BENCHMARK_RESULTS_START -->.*<!-- BENCHMARK_RESULTS_END -->', pr_body, re.DOTALL): if re.search(r'<!-- BENCHMARK_RESULTS_START -->.*<!-- BENCHMARK_RESULTS_END -->', pr_body, re.DOTALL):
updated_body = re.sub( updated_body = re.sub(

View File

@ -1,11 +1,24 @@
#!/bin/bash #!/bin/bash
set -eou pipefail set -eou pipefail
function measure_peak_ram_and_time {
COMMAND=$1
OUTPUT_FILE=$2
OUTPUT=$(/usr/bin/time -f "%e %M" $COMMAND 2>&1 | tail -n 1)
TIME=$(echo $OUTPUT | awk '{print $1}')
PEAK_RAM_KB=$(echo $OUTPUT | awk '{print $2}')
PEAK_RAM_MB=$(echo "scale=2; $PEAK_RAM_KB / 1024" | bc)
echo "Time: ${TIME}s Peak RAM: ${PEAK_RAM_MB}MB" > $OUTPUT_FILE
}
function run_benchmarks_for_folder { function run_benchmarks_for_folder {
echo "Running benchmarks for $1" echo "Running benchmarks for $1"
FOLDER=$1 FOLDER=$1
RESULTS_FOLDER=$2 RESULTS_FOLDER=$2
SCRIPTS_FOLDER=$3
mkdir -p $RESULTS_FOLDER mkdir -p $RESULTS_FOLDER
@ -13,14 +26,47 @@ function run_benchmarks_for_folder {
./$BENCHMARKS_FOLDER/match-bench "./$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/match_mld.bench" ./$BENCHMARKS_FOLDER/match-bench "./$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/match_mld.bench"
./$BENCHMARKS_FOLDER/match-bench "./$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/match_ch.bench" ./$BENCHMARKS_FOLDER/match-bench "./$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/match_ch.bench"
./$BENCHMARKS_FOLDER/route-bench "./$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/route_mld.bench" || true # TODO: remove `true` when this benchmark will be merged to master ./$BENCHMARKS_FOLDER/route-bench "./$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/route_mld.bench"
./$BENCHMARKS_FOLDER/route-bench "./$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/route_ch.bench" || true # TODO: remove `true` when this benchmark will be merged to master ./$BENCHMARKS_FOLDER/route-bench "./$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/route_ch.bench"
./$BENCHMARKS_FOLDER/alias-bench > "$RESULTS_FOLDER/alias.bench" ./$BENCHMARKS_FOLDER/alias-bench > "$RESULTS_FOLDER/alias.bench"
./$BENCHMARKS_FOLDER/json-render-bench "./$FOLDER/src/benchmarks/portugal_to_korea.json" > "$RESULTS_FOLDER/json-render.bench" ./$BENCHMARKS_FOLDER/json-render-bench "./$FOLDER/src/benchmarks/portugal_to_korea.json" > "$RESULTS_FOLDER/json-render.bench"
./$BENCHMARKS_FOLDER/packedvector-bench > "$RESULTS_FOLDER/packedvector.bench" ./$BENCHMARKS_FOLDER/packedvector-bench > "$RESULTS_FOLDER/packedvector.bench"
./$BENCHMARKS_FOLDER/rtree-bench "./$FOLDER/test/data/monaco.osrm.ramIndex" "./$FOLDER/test/data/monaco.osrm.fileIndex" "./$FOLDER/test/data/monaco.osrm.nbg_nodes" > "$RESULTS_FOLDER/rtree.bench" ./$BENCHMARKS_FOLDER/rtree-bench "./$FOLDER/test/data/monaco.osrm.ramIndex" "./$FOLDER/test/data/monaco.osrm.fileIndex" "./$FOLDER/test/data/monaco.osrm.nbg_nodes" > "$RESULTS_FOLDER/rtree.bench"
BINARIES_FOLDER="$FOLDER/build"
cp ~/data.osm.pbf $FOLDER
measure_peak_ram_and_time "$BINARIES_FOLDER/osrm-extract -p $FOLDER/profiles/car.lua $FOLDER/data.osm.pbf" "$RESULTS_FOLDER/osrm_extract.bench"
measure_peak_ram_and_time "$BINARIES_FOLDER/osrm-partition $FOLDER/data.osrm" "$RESULTS_FOLDER/osrm_partition.bench"
measure_peak_ram_and_time "$BINARIES_FOLDER/osrm-customize $FOLDER/data.osrm" "$RESULTS_FOLDER/osrm_customize.bench"
measure_peak_ram_and_time "$BINARIES_FOLDER/osrm-contract $FOLDER/data.osrm" "$RESULTS_FOLDER/osrm_contract.bench"
for BENCH in nearest table trip route match; do
./$BENCHMARKS_FOLDER/bench "$FOLDER/data.osrm" mld ~/gps_traces.csv ${BENCH} > "$RESULTS_FOLDER/random_${BENCH}_mld.bench" || true
./$BENCHMARKS_FOLDER/bench "$FOLDER/data.osrm" ch ~/gps_traces.csv ${BENCH} > "$RESULTS_FOLDER/random_${BENCH}_ch.bench" || true
done
for ALGORITHM in ch mld; do
$BINARIES_FOLDER/osrm-routed --algorithm $ALGORITHM $FOLDER/data.osrm &
OSRM_ROUTED_PID=$!
# wait for osrm-routed to start
if ! curl --retry-delay 3 --retry 10 --retry-all-errors "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true"; then
echo "osrm-routed failed to start for algorithm $ALGORITHM"
kill -9 $OSRM_ROUTED_PID
continue
fi
for METHOD in route nearest trip table match; do
python3 $SCRIPTS_FOLDER/scripts/ci/e2e_benchmark.py --host http://localhost:5000 --method $METHOD --num_requests 1000 > $RESULTS_FOLDER/e2e_${METHOD}_${ALGORITHM}.bench
done
kill -9 $OSRM_ROUTED_PID
done
} }
run_benchmarks_for_folder $1 "${1}_results" run_benchmarks_for_folder $1 "${1}_results" $2
run_benchmarks_for_folder $2 "${2}_results" run_benchmarks_for_folder $2 "${2}_results" $2

View File

@ -1,95 +0,0 @@
@ECHO OFF
SETLOCAL
SET EL=0
ECHO NUMBER_OF_PROCESSORS^: %NUMBER_OF_PROCESSORS%
SET PROJECT_DIR=%CD%
SET CONFIGURATION=Release
mkdir build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
cd build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
cmake -DENABLE_CONAN=ON -DENABLE_NODE_BINDINGS=ON -DCMAKE_BUILD_TYPE=%CONFIGURATION% -G "Visual Studio 17 2022" ..
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
msbuild OSRM.sln ^
/p:Configuration=%CONFIGURATION% ^
/p:Platform=x64 ^
/t:rebuild ^
/p:BuildInParallel=true ^
/m:%NUMBER_OF_PROCESSORS% ^
/toolsversion:Current ^
/clp:Verbosity=quiet ^
/nologo
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
CD %PROJECT_DIR%\build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running extractor-tests.exe ...
unit_tests\%CONFIGURATION%\extractor-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running contractor-tests.exe ...
unit_tests\%CONFIGURATION%\contractor-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running engine-tests.exe ...
unit_tests\%CONFIGURATION%\engine-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running util-tests.exe ...
unit_tests\%CONFIGURATION%\util-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running server-tests.exe ...
unit_tests\%CONFIGURATION%\server-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running partitioner-tests.exe ...
unit_tests\%CONFIGURATION%\partitioner-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running customizer-tests.exe ...
unit_tests\%CONFIGURATION%\customizer-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
SET test_region=monaco
SET test_region_ch=ch\monaco
SET test_region_corech=corech\monaco
SET test_region_mld=mld\monaco
SET test_osm=%test_region%.osm.pbf
COPY %PROJECT_DIR%\test\data\%test_region%.osm.pbf %test_osm%
%CONFIGURATION%\osrm-extract.exe -p %PROJECT_DIR%\profiles\car.lua %test_osm%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
MKDIR ch
XCOPY %test_region%.osrm.* ch\
XCOPY %test_region%.osrm ch\
MKDIR corech
XCOPY %test_region%.osrm.* corech\
XCOPY %test_region%.osrm corech\
MKDIR mld
XCOPY %test_region%.osrm.* mld\
XCOPY %test_region%.osrm mld\
%CONFIGURATION%\osrm-contract.exe %test_region_ch%.osrm
%CONFIGURATION%\osrm-contract.exe --core 0.8 %test_region_corech%.osrm
%CONFIGURATION%\osrm-partition.exe %test_region_mld%.osrm
%CONFIGURATION%\osrm-customize.exe %test_region_mld%.osrm
XCOPY /Y ch\*.* ..\test\data\ch\
XCOPY /Y corech\*.* ..\test\data\corech\
XCOPY /Y mld\*.* ..\test\data\mld\
unit_tests\%CONFIGURATION%\library-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
:ERROR
ECHO ~~~~~~~~~~~~~~~~~~~~~~ ERROR %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ECHO ERRORLEVEL^: %ERRORLEVEL%
SET EL=%ERRORLEVEL%
:DONE
ECHO ~~~~~~~~~~~~~~~~~~~~~~ DONE %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EXIT /b %EL%

View File

@ -12,14 +12,11 @@ set -o nounset
OSMIUM_PATH="osmcode/libosmium" OSMIUM_PATH="osmcode/libosmium"
OSMIUM_TAG=v2.14.0 OSMIUM_TAG=v2.14.0
VARIANT_PATH="mapbox/variant"
VARIANT_TAG=v1.2.0
SOL_PATH="ThePhD/sol2" SOL_PATH="ThePhD/sol2"
SOL_TAG=v2.17.5 SOL_TAG=v3.3.0
RAPIDJSON_PATH="Tencent/rapidjson" RAPIDJSON_PATH="Tencent/rapidjson"
RAPIDJSON_TAG=v1.1.0 RAPIDJSON_TAG=f9d53419e912910fd8fa57d5705fa41425428c35
MICROTAR_PATH="rxi/microtar" MICROTAR_PATH="rxi/microtar"
MICROTAR_TAG=v0.1.0 MICROTAR_TAG=v0.1.0
@ -56,6 +53,6 @@ function update_subtree () {
} }
## Update dependencies ## Update dependencies
for dep in osmium variant sol rapidjson microtar protozero vtzero fmt; do for dep in osmium sol rapidjson microtar protozero vtzero fmt; do
update_subtree $dep update_subtree $dep
done done

View File

@ -18,6 +18,7 @@ target_link_libraries(rtree-bench
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_SHAPEFILE}) ${MAYBE_SHAPEFILE})
add_executable(match-bench add_executable(match-bench
EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL
${MatchBenchmarkSources} ${MatchBenchmarkSources}
@ -35,6 +36,7 @@ add_executable(route-bench
route.cpp route.cpp
$<TARGET_OBJECTS:UTIL>) $<TARGET_OBJECTS:UTIL>)
target_link_libraries(route-bench target_link_libraries(route-bench
osrm osrm
${BOOST_BASE_LIBRARIES} ${BOOST_BASE_LIBRARIES}
@ -42,6 +44,18 @@ target_link_libraries(route-bench
${TBB_LIBRARIES} ${TBB_LIBRARIES}
${MAYBE_SHAPEFILE}) ${MAYBE_SHAPEFILE})
add_executable(bench
EXCLUDE_FROM_ALL
bench.cpp
$<TARGET_OBJECTS:UTIL>)
target_link_libraries(bench
osrm
${BOOST_BASE_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${TBB_LIBRARIES}
${MAYBE_SHAPEFILE})
add_executable(json-render-bench add_executable(json-render-bench
EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL
json_render.cpp json_render.cpp
@ -85,5 +99,6 @@ add_custom_target(benchmarks
packedvector-bench packedvector-bench
match-bench match-bench
route-bench route-bench
bench
json-render-bench json-render-bench
alias-bench) alias-bench)

573
src/benchmarks/bench.cpp Normal file
View File

@ -0,0 +1,573 @@
#include "osrm/match_parameters.hpp"
#include "osrm/nearest_parameters.hpp"
#include "osrm/table_parameters.hpp"
#include "osrm/trip_parameters.hpp"
#include "engine/engine_config.hpp"
#include "util/coordinate.hpp"
#include "util/timing_util.hpp"
#include "osrm/route_parameters.hpp"
#include "osrm/coordinate.hpp"
#include "osrm/engine_config.hpp"
#include "osrm/json_container.hpp"
#include "osrm/osrm.hpp"
#include "osrm/status.hpp"
#include <boost/assert.hpp>
#include <boost/optional/optional.hpp>
#include <cstdlib>
#include <exception>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <optional>
#include <ostream>
#include <random>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <vector>
using namespace osrm;
namespace
{
class GPSTraces
{
private:
std::set<int> trackIDs;
std::unordered_map<int /* track id */, std::vector<osrm::util::Coordinate>> traces;
std::vector<osrm::util::Coordinate> coordinates;
mutable std::mt19937 gen;
public:
GPSTraces(int seed) : gen(std::random_device{}()) { gen.seed(seed); }
bool readCSV(const std::string &filename)
{
std::ifstream file(filename);
if (!file.is_open())
{
std::cerr << "Error opening file: " << filename << std::endl;
return false;
}
std::string line;
std::getline(file, line);
while (std::getline(file, line))
{
std::istringstream ss(line);
std::string token;
int trackID;
double latitude, longitude;
std::string time;
std::getline(ss, token, ',');
trackID = std::stoi(token);
std::getline(ss, token, ',');
latitude = std::stod(token);
std::getline(ss, token, ',');
longitude = std::stod(token);
// handle empty fields
if (std::getline(ss, token, ','))
{
time = token;
}
trackIDs.insert(trackID);
traces[trackID].emplace_back(osrm::util::Coordinate{
osrm::util::FloatLongitude{longitude}, osrm::util::FloatLatitude{latitude}});
coordinates.emplace_back(osrm::util::Coordinate{osrm::util::FloatLongitude{longitude},
osrm::util::FloatLatitude{latitude}});
}
file.close();
return true;
}
const osrm::util::Coordinate &getRandomCoordinate() const
{
std::uniform_int_distribution<> dis(0, coordinates.size() - 1);
return coordinates[dis(gen)];
}
const std::vector<osrm::util::Coordinate> &getRandomTrace() const
{
std::uniform_int_distribution<> dis(0, trackIDs.size() - 1);
auto it = trackIDs.begin();
std::advance(it, dis(gen));
return traces.at(*it);
}
};
class Statistics
{
public:
void push(double timeMs)
{
times.push_back(timeMs);
sorted = false;
}
double mean() { return sum() / times.size(); }
double sum()
{
double sum = 0;
for (auto time : times)
{
sum += time;
}
return sum;
}
double min() { return *std::min_element(times.begin(), times.end()); }
double max() { return *std::max_element(times.begin(), times.end()); }
double percentile(double p)
{
const auto &times = getTimes();
return times[static_cast<size_t>(p * times.size())];
}
private:
std::vector<double> getTimes()
{
if (!sorted)
{
std::sort(times.begin(), times.end());
sorted = true;
}
return times;
}
std::vector<double> times;
bool sorted = false;
};
std::ostream &operator<<(std::ostream &os, Statistics &statistics)
{
os << std::fixed << std::setprecision(2);
os << "total: " << statistics.sum() << "ms" << std::endl;
os << "avg: " << statistics.mean() << "ms" << std::endl;
os << "min: " << statistics.min() << "ms" << std::endl;
os << "max: " << statistics.max() << "ms" << std::endl;
os << "p99: " << statistics.percentile(0.99) << "ms" << std::endl;
return os;
}
void runRouteBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces)
{
struct Benchmark
{
std::string name;
size_t coordinates;
RouteParameters::OverviewType overview;
bool steps = false;
std::optional<size_t> alternatives = std::nullopt;
std::optional<double> radius = std::nullopt;
};
auto run_benchmark = [&](const Benchmark &benchmark)
{
Statistics statistics;
auto NUM = 10000;
for (int i = 0; i < NUM; ++i)
{
RouteParameters params;
params.overview = benchmark.overview;
params.steps = benchmark.steps;
for (size_t i = 0; i < benchmark.coordinates; ++i)
{
params.coordinates.push_back(gpsTraces.getRandomCoordinate());
}
if (benchmark.alternatives)
{
params.alternatives = *benchmark.alternatives;
}
if (benchmark.radius)
{
params.radiuses = std::vector<boost::optional<double>>(
params.coordinates.size(), boost::make_optional(*benchmark.radius));
}
engine::api::ResultT result = json::Object();
TIMER_START(routes);
const auto rc = osrm.Route(params, result);
TIMER_STOP(routes);
statistics.push(TIMER_MSEC(routes));
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok || json_result.values.find("routes") == json_result.values.end())
{
auto code = std::get<json::String>(json_result.values["code"]).value;
if (code != "NoSegment" && code != "NoRoute")
{
throw std::runtime_error{"Couldn't route: " + code};
}
}
}
std::cout << benchmark.name << std::endl;
std::cout << statistics << std::endl;
};
std::vector<Benchmark> benchmarks = {
{"10000 routes, 3 coordinates, no alternatives, overview=full, steps=true",
3,
RouteParameters::OverviewType::Full,
true,
std::nullopt},
{"10000 routes, 2 coordinates, no alternatives, overview=full, steps=true",
2,
RouteParameters::OverviewType::Full,
true,
std::nullopt},
{"10000 routes, 2 coordinates, 3 alternatives, overview=full, steps=true",
2,
RouteParameters::OverviewType::Full,
true,
3},
{"10000 routes, 3 coordinates, no alternatives, overview=false, steps=false",
3,
RouteParameters::OverviewType::False,
false,
std::nullopt},
{"10000 routes, 2 coordinates, no alternatives, overview=false, steps=false",
2,
RouteParameters::OverviewType::False,
false,
std::nullopt},
{"10000 routes, 2 coordinates, 3 alternatives, overview=false, steps=false",
2,
RouteParameters::OverviewType::False,
false,
3},
{"10000 routes, 3 coordinates, no alternatives, overview=false, steps=false, radius=750",
3,
RouteParameters::OverviewType::False,
false,
std::nullopt,
750},
{"10000 routes, 2 coordinates, no alternatives, overview=false, steps=false, radius=750",
2,
RouteParameters::OverviewType::False,
false,
std::nullopt,
750},
{"10000 routes, 2 coordinates, 3 alternatives, overview=false, steps=false, radius=750",
2,
RouteParameters::OverviewType::False,
false,
3,
750}
};
for (const auto &benchmark : benchmarks)
{
run_benchmark(benchmark);
}
}
void runMatchBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces)
{
struct Benchmark
{
std::string name;
std::optional<size_t> radius = std::nullopt;
};
auto run_benchmark = [&](const Benchmark &benchmark)
{
Statistics statistics;
auto NUM = 1000;
for (int i = 0; i < NUM; ++i)
{
engine::api::ResultT result = json::Object();
engine::api::MatchParameters params;
params.coordinates = gpsTraces.getRandomTrace();
params.radiuses = {};
if (benchmark.radius)
{
for (size_t index = 0; index < params.coordinates.size(); ++index)
{
params.radiuses.emplace_back(*benchmark.radius);
}
}
TIMER_START(match);
const auto rc = osrm.Match(params, result);
TIMER_STOP(match);
statistics.push(TIMER_MSEC(match));
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok ||
json_result.values.find("matchings") == json_result.values.end())
{
auto code = std::get<json::String>(json_result.values["code"]).value;
if (code != "NoSegment" && code != "NoMatch")
{
throw std::runtime_error{"Couldn't route: " + code};
}
}
}
std::cout << benchmark.name << std::endl;
std::cout << statistics << std::endl;
};
std::vector<Benchmark> benchmarks = {{"1000 matches, default radius"},
{"1000 matches, radius=10", 10},
{"1000 matches, radius=20", 20}};
for (const auto &benchmark : benchmarks)
{
run_benchmark(benchmark);
}
}
void runNearestBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces)
{
struct Benchmark
{
std::string name;
std::optional<size_t> number_of_results = std::nullopt;
};
auto run_benchmark = [&](const Benchmark &benchmark)
{
Statistics statistics;
auto NUM = 10000;
for (int i = 0; i < NUM; ++i)
{
engine::api::ResultT result = json::Object();
NearestParameters params;
params.coordinates.push_back(gpsTraces.getRandomCoordinate());
if (benchmark.number_of_results)
{
params.number_of_results = *benchmark.number_of_results;
}
TIMER_START(nearest);
const auto rc = osrm.Nearest(params, result);
TIMER_STOP(nearest);
statistics.push(TIMER_MSEC(nearest));
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok ||
json_result.values.find("waypoints") == json_result.values.end())
{
auto code = std::get<json::String>(json_result.values["code"]).value;
if (code != "NoSegment")
{
throw std::runtime_error{"Couldn't find nearest point"};
}
}
}
std::cout << benchmark.name << std::endl;
std::cout << statistics << std::endl;
};
std::vector<Benchmark> benchmarks = {{"10000 nearest, number_of_results=1", 1},
{"10000 nearest, number_of_results=5", 5},
{"10000 nearest, number_of_results=10", 10}};
for (const auto &benchmark : benchmarks)
{
run_benchmark(benchmark);
}
}
void runTripBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces)
{
struct Benchmark
{
std::string name;
size_t coordinates;
};
auto run_benchmark = [&](const Benchmark &benchmark)
{
Statistics statistics;
auto NUM = 1000;
for (int i = 0; i < NUM; ++i)
{
engine::api::ResultT result = json::Object();
TripParameters params;
params.roundtrip = true;
for (size_t i = 0; i < benchmark.coordinates; ++i)
{
params.coordinates.push_back(gpsTraces.getRandomCoordinate());
}
TIMER_START(trip);
const auto rc = osrm.Trip(params, result);
TIMER_STOP(trip);
statistics.push(TIMER_MSEC(trip));
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok || json_result.values.find("trips") == json_result.values.end())
{
auto code = std::get<json::String>(json_result.values["code"]).value;
if (code != "NoSegment")
{
throw std::runtime_error{"Couldn't find trip"};
}
}
}
std::cout << benchmark.name << std::endl;
std::cout << statistics << std::endl;
};
std::vector<Benchmark> benchmarks = {
{"1000 trips, 3 coordinates", 3},
{"1000 trips, 4 coordinates", 4},
{"1000 trips, 5 coordinates", 5},
};
for (const auto &benchmark : benchmarks)
{
run_benchmark(benchmark);
}
}
void runTableBenchmark(const OSRM &osrm, const GPSTraces &gpsTraces)
{
struct Benchmark
{
std::string name;
size_t coordinates;
};
auto run_benchmark = [&](const Benchmark &benchmark)
{
Statistics statistics;
auto NUM = 250;
for (int i = 0; i < NUM; ++i)
{
engine::api::ResultT result = json::Object();
TableParameters params;
for (size_t i = 0; i < benchmark.coordinates; ++i)
{
params.coordinates.push_back(gpsTraces.getRandomCoordinate());
}
TIMER_START(table);
const auto rc = osrm.Table(params, result);
TIMER_STOP(table);
statistics.push(TIMER_MSEC(table));
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok ||
json_result.values.find("durations") == json_result.values.end())
{
auto code = std::get<json::String>(json_result.values["code"]).value;
if (code != "NoSegment")
{
throw std::runtime_error{"Couldn't compute table"};
}
}
}
std::cout << benchmark.name << std::endl;
std::cout << statistics << std::endl;
};
std::vector<Benchmark> benchmarks = {{"250 tables, 3 coordinates", 3},
{"250 tables, 25 coordinates", 25},
{"250 tables, 50 coordinates", 50},
{"250 tables, 100 coordinates", 100}};
for (const auto &benchmark : benchmarks)
{
run_benchmark(benchmark);
}
}
} // namespace
int main(int argc, const char *argv[])
try
{
if (argc < 5)
{
std::cerr
<< "Usage: " << argv[0]
<< " data.osrm <mld|ch> <path to GPS traces.csv> <route|match|trip|table|nearest>\n";
return EXIT_FAILURE;
}
// 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 =
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)
OSRM osrm{config};
GPSTraces gpsTraces{42};
gpsTraces.readCSV(argv[3]);
const auto benchmarkToRun = std::string{argv[4]};
if (benchmarkToRun == "route")
{
runRouteBenchmark(osrm, gpsTraces);
}
else if (benchmarkToRun == "match")
{
runMatchBenchmark(osrm, gpsTraces);
}
else if (benchmarkToRun == "nearest")
{
runNearestBenchmark(osrm, gpsTraces);
}
else if (benchmarkToRun == "trip")
{
runTripBenchmark(osrm, gpsTraces);
}
else if (benchmarkToRun == "table")
{
runTableBenchmark(osrm, gpsTraces);
}
else
{
std::cerr << "Unknown benchmark: " << benchmarkToRun << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
catch (const std::exception &e)
{
std::cerr << "Error: " << e.what() << std::endl;
return EXIT_FAILURE;
}

View File

@ -86,7 +86,7 @@ json::Object load(const char *filename)
json::Value result; json::Value result;
convert(document, result); convert(document, result);
return result.get<json::Object>(); return std::get<json::Object>(result);
} }
} // namespace } // namespace

View File

@ -232,9 +232,9 @@ try
{ {
engine::api::ResultT result = json::Object(); engine::api::ResultT result = json::Object();
const auto rc = osrm.Match(params, result); const auto rc = osrm.Match(params, result);
auto &json_result = result.get<json::Object>(); auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok || if (rc != Status::Ok ||
json_result.values.at("matchings").get<json::Array>().values.size() != 1) std::get<json::Array>(json_result.values.at("matchings")).values.size() != 1)
{ {
throw std::runtime_error{"Couldn't match"}; throw std::runtime_error{"Couldn't match"};
} }

View File

@ -76,7 +76,7 @@ try
{ {
engine::api::ResultT result = json::Object(); engine::api::ResultT result = json::Object();
const auto rc = osrm.Route(params, result); const auto rc = osrm.Route(params, result);
auto &json_result = result.get<json::Object>(); auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok || json_result.values.find("routes") == json_result.values.end()) if (rc != Status::Ok || json_result.values.find("routes") == json_result.values.end())
{ {
throw std::runtime_error{"Couldn't route"}; throw std::runtime_error{"Couldn't route"};

View File

@ -74,12 +74,12 @@ std::string waypointTypeToString(const guidance::WaypointType waypoint_type)
return waypoint_type_names[static_cast<std::size_t>(waypoint_type)]; return waypoint_type_names[static_cast<std::size_t>(waypoint_type)];
} }
util::json::Array coordinateToLonLat(const util::Coordinate &coordinate) util::json::Value coordinateToLonLat(const util::Coordinate &coordinate)
{ {
util::json::Array array; util::json::Array array;
array.values.push_back(static_cast<double>(util::toFloating(coordinate.lon))); array.values.push_back(static_cast<double>(util::toFloating(coordinate.lon)));
array.values.push_back(static_cast<double>(util::toFloating(coordinate.lat))); array.values.push_back(static_cast<double>(util::toFloating(coordinate.lat)));
return array; return util::json::Value{std::move(array)};
} }
} // namespace detail } // namespace detail

View File

@ -125,9 +125,9 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
if (previous_is_straight) if (previous_is_straight)
{ {
if (isLeftTurn(current_inst) || is_straight_left.count(&current) > 0) if (isLeftTurn(current_inst) || is_straight_left.contains(&current))
is_straight_left.insert(&previous); is_straight_left.insert(&previous);
else if (isRightTurn(current_inst) || is_straight_right.count(&current) > 0) else if (isRightTurn(current_inst) || is_straight_right.contains(&current))
is_straight_right.insert(&previous); is_straight_right.insert(&previous);
} }
@ -190,9 +190,9 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
// //
// coming from right, going to left (in direction of way) -> handle as left turn // coming from right, going to left (in direction of way) -> handle as left turn
if (is_straight_left.count(&current) > 0) if (is_straight_left.contains(&current))
anticipate_for_left_turn(); anticipate_for_left_turn();
else if (is_straight_right.count(&current) > 0) else if (is_straight_right.contains(&current))
anticipate_for_right_turn(); anticipate_for_right_turn();
else // FIXME: right-sided driving else // FIXME: right-sided driving
anticipate_for_right_turn(); anticipate_for_right_turn();

View File

@ -497,13 +497,13 @@ void encodeVectorTile(const DataFacadeBase &facade,
{ {
// Calculate the speed for this line // Calculate the speed for this line
std::uint32_t speed_kmh_idx = static_cast<std::uint32_t>( std::uint32_t speed_kmh_idx = static_cast<std::uint32_t>(
round(length / from_alias<double>(forward_duration) * 10 * 3.6)); std::round(length / from_alias<double>(forward_duration) * 10 * 3.6));
// Rate values are in meters per weight-unit - and similar to speeds, we // Rate values are in meters per weight-unit - and similar to speeds, we
// present 1 decimal place of precision (these values are added as // present 1 decimal place of precision (these values are added as
// double/10) lower down // double/10) lower down
std::uint32_t forward_rate = static_cast<std::uint32_t>( std::uint32_t forward_rate = static_cast<std::uint32_t>(
round(length / from_alias<double>(forward_weight) * 10.)); std::round(length / from_alias<double>(forward_weight) * 10.));
auto tile_line = coordinatesToTileLine(a, b, tile_bbox); auto tile_line = coordinatesToTileLine(a, b, tile_bbox);
if (!tile_line.empty()) if (!tile_line.empty())
@ -531,13 +531,13 @@ void encodeVectorTile(const DataFacadeBase &facade,
{ {
// Calculate the speed for this line // Calculate the speed for this line
std::uint32_t speed_kmh_idx = static_cast<std::uint32_t>( std::uint32_t speed_kmh_idx = static_cast<std::uint32_t>(
round(length / from_alias<double>(reverse_duration) * 10 * 3.6)); std::round(length / from_alias<double>(reverse_duration) * 10 * 3.6));
// Rate values are in meters per weight-unit - and similar to speeds, we // Rate values are in meters per weight-unit - and similar to speeds, we
// present 1 decimal place of precision (these values are added as // present 1 decimal place of precision (these values are added as
// double/10) lower down // double/10) lower down
std::uint32_t reverse_rate = static_cast<std::uint32_t>( std::uint32_t reverse_rate = static_cast<std::uint32_t>(
round(length / from_alias<double>(reverse_weight) * 10.)); std::round(length / from_alias<double>(reverse_weight) * 10.));
auto tile_line = coordinatesToTileLine(b, a, tile_bbox); auto tile_line = coordinatesToTileLine(b, a, tile_bbox);
if (!tile_line.empty()) if (!tile_line.empty())
@ -663,7 +663,7 @@ Status TilePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
{ {
BOOST_ASSERT(parameters.IsValid()); BOOST_ASSERT(parameters.IsValid());
auto &pbf_buffer = result.get<std::string>(); auto &pbf_buffer = std::get<std::string>(result);
const auto &facade = algorithms.GetFacade(); const auto &facade = algorithms.GetFacade();
auto edges = getEdges(facade, parameters.x, parameters.y, parameters.z); auto edges = getEdges(facade, parameters.x, parameters.y, parameters.z);
auto segregated_nodes = getSegregatedNodes(facade, edges); auto segregated_nodes = getSegregatedNodes(facade, edges);

View File

@ -248,7 +248,7 @@ filterViaCandidatesByViaNotOnPath(const WeightedViaNodePackedPath &path, RandIt
for (const auto &edge : path.path) for (const auto &edge : path.path)
nodes.insert(std::get<1>(edge)); nodes.insert(std::get<1>(edge));
const auto via_on_path = [&](const auto via) { return nodes.count(via.node) > 0; }; const auto via_on_path = [&](const auto via) { return nodes.contains(via.node); };
return std::remove_if(first, last, via_on_path); return std::remove_if(first, last, via_on_path);
} }
@ -308,7 +308,7 @@ RandIt filterPackedPathsByCellSharing(RandIt first,
{ {
const auto source_cell = get_cell(std::get<0>(edge)); const auto source_cell = get_cell(std::get<0>(edge));
const auto target_cell = get_cell(std::get<1>(edge)); const auto target_cell = get_cell(std::get<1>(edge));
return cells.count(source_cell) < 1 && cells.count(target_cell) < 1; return !cells.contains(source_cell) && !cells.contains(target_cell);
}; };
const auto different = std::count_if(begin(packed.path), end(packed.path), not_seen); const auto different = std::count_if(begin(packed.path), end(packed.path), not_seen);
@ -491,7 +491,7 @@ RandIt filterUnpackedPathsBySharing(RandIt first,
{ {
auto node_duration = facade.GetNodeDuration(node); auto node_duration = facade.GetNodeDuration(node);
total_duration += node_duration; total_duration += node_duration;
if (nodes.count(node) > 0) if (nodes.contains(node))
{ {
return duration + node_duration; return duration + node_duration;
} }

View File

@ -325,7 +325,7 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
EdgeDuration initial_duration, EdgeDuration initial_duration,
EdgeDistance initial_distance) EdgeDistance initial_distance)
{ {
if (target_nodes_index.count(node)) if (target_nodes_index.contains(node))
{ {
// Source and target on the same edge node. If target is not reachable directly via // Source and target on the same edge node. If target is not reachable directly via
// the node (e.g destination is before source on oneway segment) we want to allow // the node (e.g destination is before source on oneway segment) we want to allow

View File

@ -0,0 +1,60 @@
#include "engine/routing_algorithms/routing_base_mld.hpp"
namespace osrm::engine::routing_algorithms::mld
{
double getNetworkDistance(SearchEngineData<mld::Algorithm> &engine_working_data,
const DataFacade<mld::Algorithm> &facade,
typename SearchEngineData<mld::Algorithm>::QueryHeap &forward_heap,
typename SearchEngineData<mld::Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound)
{
forward_heap.Clear();
reverse_heap.Clear();
const PhantomEndpoints endpoints{source_phantom, target_phantom};
insertNodesInHeaps(forward_heap, reverse_heap, 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();
}
BOOST_ASSERT(unpacked_nodes.size() >= 1);
EdgeDistance distance = {0.0};
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

View File

@ -49,7 +49,7 @@ std::vector<TurnData> generateTurns(const datafacade &facade,
{ {
// operator[] will construct an empty vector at [edge.u] if there is no value. // operator[] will construct an empty vector at [edge.u] if there is no value.
directed_graph[edge.u].push_back({edge.v, edge.forward_segment_id.id}); directed_graph[edge.u].push_back({edge.v, edge.forward_segment_id.id});
if (edge_based_node_info.count(edge.forward_segment_id.id) == 0) if (!edge_based_node_info.contains(edge.forward_segment_id.id))
{ {
edge_based_node_info[edge.forward_segment_id.id] = {true, get_geometry_id(edge)}; edge_based_node_info[edge.forward_segment_id.id] = {true, get_geometry_id(edge)};
} }
@ -64,7 +64,7 @@ std::vector<TurnData> generateTurns(const datafacade &facade,
if (edge.reverse_segment_id.enabled) if (edge.reverse_segment_id.enabled)
{ {
directed_graph[edge.v].push_back({edge.u, edge.reverse_segment_id.id}); directed_graph[edge.v].push_back({edge.u, edge.reverse_segment_id.id});
if (edge_based_node_info.count(edge.reverse_segment_id.id) == 0) if (!edge_based_node_info.contains(edge.reverse_segment_id.id))
{ {
edge_based_node_info[edge.reverse_segment_id.id] = {false, get_geometry_id(edge)}; edge_based_node_info[edge.reverse_segment_id.id] = {false, get_geometry_id(edge)};
} }
@ -106,7 +106,7 @@ std::vector<TurnData> generateTurns(const datafacade &facade,
{ {
// If the target of this edge doesn't exist in our directed // If the target of this edge doesn't exist in our directed
// graph, it's probably outside the tile, so we can skip it // graph, it's probably outside the tile, so we can skip it
if (directed_graph.count(approachedge.target_node) == 0) if (!directed_graph.contains(approachedge.target_node))
continue; continue;
// For each of the outgoing edges from our target coordinate // For each of the outgoing edges from our target coordinate

View File

@ -167,7 +167,7 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N
m_edge_based_node_container.nodes[nbe_to_ebn_mapping[edge_id_1]].annotation_id = m_edge_based_node_container.nodes[nbe_to_ebn_mapping[edge_id_1]].annotation_id =
forward_data.annotation_data; forward_data.annotation_data;
m_edge_based_node_container.nodes[nbe_to_ebn_mapping[edge_id_1]].segregated = m_edge_based_node_container.nodes[nbe_to_ebn_mapping[edge_id_1]].segregated =
segregated_edges.count(edge_id_1) > 0; segregated_edges.contains(edge_id_1);
if (nbe_to_ebn_mapping[edge_id_2] != SPECIAL_EDGEID) if (nbe_to_ebn_mapping[edge_id_2] != SPECIAL_EDGEID)
{ {
@ -176,7 +176,7 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N
m_edge_based_node_container.nodes[nbe_to_ebn_mapping[edge_id_2]].annotation_id = m_edge_based_node_container.nodes[nbe_to_ebn_mapping[edge_id_2]].annotation_id =
reverse_data.annotation_data; reverse_data.annotation_data;
m_edge_based_node_container.nodes[nbe_to_ebn_mapping[edge_id_2]].segregated = m_edge_based_node_container.nodes[nbe_to_ebn_mapping[edge_id_2]].segregated =
segregated_edges.count(edge_id_2) > 0; segregated_edges.contains(edge_id_2);
} }
// Add segments of edge-based nodes // Add segments of edge-based nodes
@ -382,7 +382,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
m_edge_based_node_container.nodes[edge_based_node_id].annotation_id = m_edge_based_node_container.nodes[edge_based_node_id].annotation_id =
edge_data.annotation_data; edge_data.annotation_data;
m_edge_based_node_container.nodes[edge_based_node_id].segregated = m_edge_based_node_container.nodes[edge_based_node_id].segregated =
segregated_edges.count(eid) > 0; segregated_edges.contains(eid);
const auto ebn_weight = m_edge_based_node_weights[nbe_to_ebn_mapping[eid]]; const auto ebn_weight = m_edge_based_node_weights[nbe_to_ebn_mapping[eid]];
BOOST_ASSERT((ebn_weight & EdgeWeight{0x7fffffff}) == edge_data.weight); BOOST_ASSERT((ebn_weight & EdgeWeight{0x7fffffff}) == edge_data.weight);
@ -942,7 +942,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const auto turn_nodes = NodeBasedTurn{ const auto turn_nodes = NodeBasedTurn{
incoming_edge.node, intersection_node, outgoing_edge_target}; incoming_edge.node, intersection_node, outgoing_edge_target};
const auto is_maneuver_turn = unresolved_turns.count(turn_nodes) > 0; const auto is_maneuver_turn = unresolved_turns.contains(turn_nodes);
if (is_maneuver_turn) if (is_maneuver_turn)
{ {

View File

@ -83,7 +83,7 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
} }
// check if v is an entry/exit via node for a turn restriction // check if v is an entry/exit via node for a turn restriction
if (incompressible_via_nodes.count(node_v) > 0) if (incompressible_via_nodes.contains(node_v))
{ {
continue; continue;
} }

View File

@ -6,6 +6,7 @@
#include "util/coordinate_calculation.hpp" #include "util/coordinate_calculation.hpp"
#include <boost/optional/optional_io.hpp> #include <boost/optional/optional_io.hpp>
#include <numbers>
namespace osrm::extractor::intersection namespace osrm::extractor::intersection
{ {
@ -79,11 +80,11 @@ namespace
{ {
double findAngleBisector(double alpha, double beta) double findAngleBisector(double alpha, double beta)
{ {
alpha *= M_PI / 180.; alpha *= std::numbers::pi / 180.;
beta *= M_PI / 180.; beta *= std::numbers::pi / 180.;
const auto average = const auto average =
180. * std::atan2(std::sin(alpha) + std::sin(beta), std::cos(alpha) + std::cos(beta)) / 180. * std::atan2(std::sin(alpha) + std::sin(beta), std::cos(alpha) + std::cos(beta)) *
M_PI; std::numbers::inv_pi;
return std::fmod(average + 360., 360.); return std::fmod(average + 360., 360.);
} }
@ -622,7 +623,7 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
for (const auto &outgoing_edge : outgoing_edges) for (const auto &outgoing_edge : outgoing_edges)
{ {
const auto edge_it = findEdge(edge_geometries, outgoing_edge.edge); const auto edge_it = findEdge(edge_geometries, outgoing_edge.edge);
const auto is_merged = merged_edges.count(outgoing_edge.edge) != 0; const auto is_merged = merged_edges.contains(outgoing_edge.edge);
const auto is_turn_allowed = intersection::isTurnAllowed(graph, const auto is_turn_allowed = intersection::isTurnAllowed(graph,
node_data_container, node_data_container,
restriction_map, restriction_map,

View File

@ -351,7 +351,7 @@ bool MergableRoadDetector::IsCircularShape(const NodeID intersection_node,
// ---- ---- // ---- ----
// \ / // \ /
// ------- // -------
const auto constexpr CIRCULAR_POLYGON_ISOPERIMETRIC_LOWER_BOUND = 0.85 / (4 * M_PI); const auto constexpr CIRCULAR_POLYGON_ISOPERIMETRIC_LOWER_BOUND = 0.85 / (4 * std::numbers::pi);
if (connect_again && coordinates_to_the_left.front() == coordinates_to_the_left.back()) if (connect_again && coordinates_to_the_left.front() == coordinates_to_the_left.back())
{ // if the left and right roads connect again and are closed polygons ... { // if the left and right roads connect again and are closed polygons ...
const auto area = util::coordinate_calculation::computeArea(coordinates_to_the_left); const auto area = util::coordinate_calculation::computeArea(coordinates_to_the_left);
@ -359,7 +359,7 @@ bool MergableRoadDetector::IsCircularShape(const NodeID intersection_node,
const auto area_to_squared_perimeter_ratio = std::abs(area) / (perimeter * perimeter); const auto area_to_squared_perimeter_ratio = std::abs(area) / (perimeter * perimeter);
// then don't merge roads if A/L² is greater than the lower bound // then don't merge roads if A/L² is greater than the lower bound
BOOST_ASSERT(area_to_squared_perimeter_ratio <= 1. / (4 * M_PI)); BOOST_ASSERT(area_to_squared_perimeter_ratio <= 1. / (4 * std::numbers::pi));
if (area_to_squared_perimeter_ratio >= CIRCULAR_POLYGON_ISOPERIMETRIC_LOWER_BOUND) if (area_to_squared_perimeter_ratio >= CIRCULAR_POLYGON_ISOPERIMETRIC_LOWER_BOUND)
return true; return true;
} }

View File

@ -40,8 +40,8 @@ RasterDatum RasterSource::GetRasterData(const int lon, const int lat) const
return {}; return {};
} }
const std::size_t xth = static_cast<std::size_t>(round((lon - xmin) / xstep)); const std::size_t xth = static_cast<std::size_t>(std::round((lon - xmin) / xstep));
const std::size_t yth = static_cast<std::size_t>(round((ymax - lat) / ystep)); const std::size_t yth = static_cast<std::size_t>(std::round((ymax - lat) / ystep));
return {raster_data(xth, yth)}; return {raster_data(xth, yth)};
} }

View File

@ -28,7 +28,7 @@ bool SuffixTable::isSuffix(const std::string &possible_suffix) const
bool SuffixTable::isSuffix(std::string_view possible_suffix) const bool SuffixTable::isSuffix(std::string_view possible_suffix) const
{ {
return suffix_set.count(possible_suffix) > 0; return suffix_set.contains(possible_suffix);
} }
} // namespace osrm::extractor } // namespace osrm::extractor

View File

@ -18,7 +18,7 @@ std::size_t WayRestrictionMap::NumberOfDuplicatedNodes() const
bool WayRestrictionMap::IsViaWayEdge(const NodeID from, const NodeID to) const bool WayRestrictionMap::IsViaWayEdge(const NodeID from, const NodeID to) const
{ {
return restriction_graph.via_edge_to_node.count({from, to}) > 0; return restriction_graph.via_edge_to_node.contains({from, to});
} }
std::vector<DuplicatedNodeID> WayRestrictionMap::DuplicatedNodeIDs(const NodeID from, std::vector<DuplicatedNodeID> WayRestrictionMap::DuplicatedNodeIDs(const NodeID from,

View File

@ -302,7 +302,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
if (roundabout == circular) if (roundabout == circular)
return RoundaboutType::None; return RoundaboutType::None;
while (0 == roundabout_nodes.count(last_node)) while (!roundabout_nodes.contains(last_node))
{ {
// only count exits/entry locations // only count exits/entry locations
if (node_based_graph.GetOutDegree(last_node) > 2) if (node_based_graph.GetOutDegree(last_node) > 2)
@ -337,7 +337,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
return RoundaboutType::RoundaboutIntersection; return RoundaboutType::RoundaboutIntersection;
} }
const double radius = roundabout_length / (2 * M_PI); const double radius = roundabout_length * 0.5 * std::numbers::inv_pi;
// Looks like a rotary: large roundabout with dedicated name // Looks like a rotary: large roundabout with dedicated name
// do we have a dedicated name for the rotary, if not its a roundabout // do we have a dedicated name for the rotary, if not its a roundabout
@ -345,8 +345,8 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
// used with a reference and without. This will be fixed automatically // used with a reference and without. This will be fixed automatically
// when we handle references separately or if the useage is more consistent // when we handle references separately or if the useage is more consistent
const auto is_rotary = (1 == roundabout_name_ids.size()) && const auto is_rotary = (1 == roundabout_name_ids.size()) &&
(circular || // (circular || //
((0 == connected_names.count(*roundabout_name_ids.begin())) && // ((!connected_names.contains(*roundabout_name_ids.begin())) && //
(radius > MAX_ROUNDABOUT_RADIUS))); (radius > MAX_ROUNDABOUT_RADIUS)));
if (is_rotary) if (is_rotary)

View File

@ -508,7 +508,7 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
}(); }();
BOOST_ASSERT(best_match != intersection.end()); BOOST_ASSERT(best_match != intersection.end());
std::size_t match_index = std::distance(intersection.begin(), best_match); std::size_t match_index = std::distance(intersection.begin(), best_match);
all_simple &= (matched_indices.count(match_index) == 0); all_simple &= (!matched_indices.contains(match_index));
matched_indices.insert(match_index); matched_indices.insert(match_index);
// in case of u-turns, we might need to activate them first // in case of u-turns, we might need to activate them first
all_simple &= (best_match->entry_allowed || all_simple &= (best_match->entry_allowed ||

View File

@ -64,7 +64,7 @@ Napi::Object Engine::Init(Napi::Env env, Napi::Object exports)
* ``` * ```
* *
* @param {Object|String} [options={shared_memory: true}] Options for creating an OSRM object or string to the `.osrm` file. * @param {Object|String} [options={shared_memory: true}] Options for creating an OSRM object or string to the `.osrm` file.
* @param {String} [options.algorithm] The algorithm to use for routing. Can be 'CH', 'CoreCH' or 'MLD'. Default is 'CH'. * @param {String} [options.algorithm] The algorithm to use for routing. Can be 'CH', or 'MLD'. Default is 'CH'.
* Make sure you prepared the dataset with the correct toolchain. * Make sure you prepared the dataset with the correct toolchain.
* @param {Boolean} [options.shared_memory] Connects to the persistent shared memory datastore. * @param {Boolean} [options.shared_memory] Connects to the persistent shared memory datastore.
* This requires you to run `osrm-datastore` prior to creating an `OSRM` object. * This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
@ -147,7 +147,7 @@ inline void async(const Napi::CallbackInfo &info,
osrm::engine::api::ResultT r; osrm::engine::api::ResultT r;
r = osrm::util::json::Object(); r = osrm::util::json::Object();
const auto status = ((*osrm).*(service))(*params, r); const auto status = ((*osrm).*(service))(*params, r);
auto &json_result = r.get<osrm::json::Object>(); auto &json_result = std::get<osrm::json::Object>(r);
ParseResult(status, json_result); ParseResult(status, json_result);
if (pluginParams.renderToBuffer) if (pluginParams.renderToBuffer)
{ {
@ -165,7 +165,7 @@ inline void async(const Napi::CallbackInfo &info,
{ {
osrm::engine::api::ResultT r = flatbuffers::FlatBufferBuilder(); osrm::engine::api::ResultT r = flatbuffers::FlatBufferBuilder();
const auto status = ((*osrm).*(service))(*params, r); const auto status = ((*osrm).*(service))(*params, r);
const auto &fbs_result = r.get<flatbuffers::FlatBufferBuilder>(); const auto &fbs_result = std::get<flatbuffers::FlatBufferBuilder>(r);
ParseResult(status, fbs_result); ParseResult(status, fbs_result);
BOOST_ASSERT(pluginParams.renderToBuffer); BOOST_ASSERT(pluginParams.renderToBuffer);
std::string result_str( std::string result_str(
@ -240,7 +240,7 @@ inline void asyncForTiles(const Napi::CallbackInfo &info,
{ {
result = std::string(); result = std::string();
const auto status = ((*osrm).*(service))(*params, result); const auto status = ((*osrm).*(service))(*params, result);
auto str_result = result.get<std::string>(); auto str_result = std::get<std::string>(result);
ParseResult(status, str_result); ParseResult(status, str_result);
} }
catch (const std::exception &e) catch (const std::exception &e)
@ -252,7 +252,7 @@ inline void asyncForTiles(const Napi::CallbackInfo &info,
{ {
Napi::HandleScope scope{Env()}; Napi::HandleScope scope{Env()};
Callback().Call({Env().Null(), render(Env(), result.get<std::string>())}); Callback().Call({Env().Null(), render(Env(), std::get<std::string>(result))});
} }
// Keeps the OSRM object alive even after shutdown until we're done with callback // Keeps the OSRM object alive even after shutdown until we're done with callback

View File

@ -36,13 +36,6 @@ OSRM::OSRM(engine::EngineConfig &config)
// Now, check that the algorithm requested can be used with the data // Now, check that the algorithm requested can be used with the data
// that's available. // that's available.
if (config.algorithm == EngineConfig::Algorithm::CoreCH)
{
util::Log(logWARNING) << "Using CoreCH is deprecated. Falling back to CH";
config.algorithm = EngineConfig::Algorithm::CH;
}
switch (config.algorithm) switch (config.algorithm)
{ {
case EngineConfig::Algorithm::CH: case EngineConfig::Algorithm::CH:
@ -65,7 +58,7 @@ Status OSRM::Route(const engine::api::RouteParameters &params, json::Object &jso
{ {
osrm::engine::api::ResultT result = json::Object(); osrm::engine::api::ResultT result = json::Object();
auto status = engine_->Route(params, result); auto status = engine_->Route(params, result);
json_result = std::move(result.get<json::Object>()); json_result = std::move(std::get<json::Object>(result));
return status; return status;
} }
@ -78,7 +71,7 @@ Status OSRM::Table(const engine::api::TableParameters &params, json::Object &jso
{ {
osrm::engine::api::ResultT result = json::Object(); osrm::engine::api::ResultT result = json::Object();
auto status = engine_->Table(params, result); auto status = engine_->Table(params, result);
json_result = std::move(result.get<json::Object>()); json_result = std::move(std::get<json::Object>(result));
return status; return status;
} }
@ -91,7 +84,7 @@ Status OSRM::Nearest(const engine::api::NearestParameters &params, json::Object
{ {
osrm::engine::api::ResultT result = json::Object(); osrm::engine::api::ResultT result = json::Object();
auto status = engine_->Nearest(params, result); auto status = engine_->Nearest(params, result);
json_result = std::move(result.get<json::Object>()); json_result = std::move(std::get<json::Object>(result));
return status; return status;
} }
@ -104,7 +97,7 @@ Status OSRM::Trip(const engine::api::TripParameters &params, json::Object &json_
{ {
osrm::engine::api::ResultT result = json::Object(); osrm::engine::api::ResultT result = json::Object();
auto status = engine_->Trip(params, result); auto status = engine_->Trip(params, result);
json_result = std::move(result.get<json::Object>()); json_result = std::move(std::get<json::Object>(result));
return status; return status;
} }
@ -118,7 +111,7 @@ Status OSRM::Match(const engine::api::MatchParameters &params, json::Object &jso
{ {
osrm::engine::api::ResultT result = json::Object(); osrm::engine::api::ResultT result = json::Object();
auto status = engine_->Match(params, result); auto status = engine_->Match(params, result);
json_result = std::move(result.get<json::Object>()); json_result = std::move(std::get<json::Object>(result));
return status; return status;
} }
@ -131,7 +124,7 @@ Status OSRM::Tile(const engine::api::TileParameters &params, std::string &str_re
{ {
osrm::engine::api::ResultT result = std::string(); osrm::engine::api::ResultT result = std::string();
auto status = engine_->Tile(params, result); auto status = engine_->Tile(params, result);
str_result = std::move(result.get<std::string>()); str_result = std::move(std::get<std::string>(result));
return status; return status;
} }

View File

@ -22,7 +22,7 @@ auto makeHasNeighborNotInCheck(const DinicMaxFlow::SourceSinkNodes &set,
return [&](const NodeID nid) return [&](const NodeID nid)
{ {
const auto is_not_contained = [&set](const BisectionEdge &edge) const auto is_not_contained = [&set](const BisectionEdge &edge)
{ return set.count(edge.target) == 0; }; { return !set.contains(edge.target); };
return view.EndEdges(nid) != return view.EndEdges(nid) !=
std::find_if(view.BeginEdges(nid), view.EndEdges(nid), is_not_contained); std::find_if(view.BeginEdges(nid), view.EndEdges(nid), is_not_contained);
}; };
@ -128,7 +128,7 @@ DinicMaxFlow::ComputeLevelGraph(const BisectionGraphView &view,
levels[node_id] = 0; levels[node_id] = 0;
level_queue.push(node_id); level_queue.push(node_id);
for (const auto &edge : view.Edges(node_id)) for (const auto &edge : view.Edges(node_id))
if (source_nodes.count(edge.target)) if (source_nodes.contains(edge.target))
levels[edge.target] = 0; levels[edge.target] = 0;
} }
// check if there is flow present on an edge // check if there is flow present on an edge
@ -139,7 +139,7 @@ DinicMaxFlow::ComputeLevelGraph(const BisectionGraphView &view,
const auto relax_node = [&](const NodeID node_id) const auto relax_node = [&](const NodeID node_id)
{ {
// don't relax sink nodes // don't relax sink nodes
if (sink_nodes.count(node_id)) if (sink_nodes.contains(node_id))
return; return;
const auto level = levels[node_id] + 1; const auto level = levels[node_id] + 1;
@ -264,7 +264,7 @@ std::vector<NodeID> DinicMaxFlow::GetAugmentingPath(LevelGraph &levels,
dfs_stack.top().edge_iterator++; dfs_stack.top().edge_iterator++;
// check if the edge is valid // check if the edge is valid
const auto has_capacity = flow[target].count(path.back()) == 0; const auto has_capacity = !flow[target].contains(path.back());
const auto descends_level_graph = levels[target] + 1 == levels[path.back()]; const auto descends_level_graph = levels[target] + 1 == levels[path.back()];
if (has_capacity && descends_level_graph) if (has_capacity && descends_level_graph)
@ -300,8 +300,9 @@ bool DinicMaxFlow::Validate(const BisectionGraphView &view,
// sink and source cannot share a common node // sink and source cannot share a common node
const auto separated = std::find_if(source_nodes.begin(), const auto separated = std::find_if(source_nodes.begin(),
source_nodes.end(), source_nodes.end(),
[&sink_nodes](const auto node) [&sink_nodes](const auto node) {
{ return sink_nodes.count(node); }) == source_nodes.end(); return sink_nodes.contains(node);
}) == source_nodes.end();
const auto invalid_id = [&view](const NodeID nid) { return nid >= view.NumberOfNodes(); }; const auto invalid_id = [&view](const NodeID nid) { return nid >= view.NumberOfNodes(); };
const auto in_range_source = const auto in_range_source =

View File

@ -15,7 +15,6 @@
#include "util/coordinate.hpp" #include "util/coordinate.hpp"
#include "util/geojson_debug_logger.hpp" #include "util/geojson_debug_logger.hpp"
#include "util/geojson_debug_policies.hpp"
#include "util/integer_range.hpp" #include "util/integer_range.hpp"
#include "util/json_container.hpp" #include "util/json_container.hpp"
#include "util/log.hpp" #include "util/log.hpp"

View File

@ -186,6 +186,7 @@ void Connection::handle_timeout(boost::system::error_code ec)
if (ec != boost::asio::error::operation_aborted) if (ec != boost::asio::error::operation_aborted)
{ {
boost::system::error_code ignore_error; boost::system::error_code ignore_error;
// NOLINTNEXTLINE(bugprone-unused-return-value)
TCP_socket.cancel(ignore_error); TCP_socket.cancel(ignore_error);
handle_shutdown(); handle_shutdown();
} }
@ -197,6 +198,7 @@ void Connection::handle_shutdown()
timer.cancel(); timer.cancel();
// Initiate graceful connection closure. // Initiate graceful connection closure.
boost::system::error_code ignore_error; boost::system::error_code ignore_error;
// NOLINTNEXTLINE(bugprone-unused-return-value)
TCP_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignore_error); TCP_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignore_error);
} }

View File

@ -21,6 +21,7 @@
#include <algorithm> #include <algorithm>
#include <string> #include <string>
#include <thread> #include <thread>
#include <variant>
namespace osrm::server namespace osrm::server
{ {
@ -38,17 +39,17 @@ void SendResponse(ServiceHandler::ResultT &result, http::reply &current_reply)
current_reply.headers.emplace_back("Access-Control-Allow-Methods", "GET"); current_reply.headers.emplace_back("Access-Control-Allow-Methods", "GET");
current_reply.headers.emplace_back("Access-Control-Allow-Headers", current_reply.headers.emplace_back("Access-Control-Allow-Headers",
"X-Requested-With, Content-Type"); "X-Requested-With, Content-Type");
if (result.is<util::json::Object>()) if (std::holds_alternative<util::json::Object>(result))
{ {
current_reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8"); current_reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8");
current_reply.headers.emplace_back("Content-Disposition", current_reply.headers.emplace_back("Content-Disposition",
"inline; filename=\"response.json\""); "inline; filename=\"response.json\"");
util::json::render(current_reply.content, result.get<util::json::Object>()); util::json::render(current_reply.content, std::get<util::json::Object>(result));
} }
else if (result.is<flatbuffers::FlatBufferBuilder>()) else if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(result))
{ {
auto &buffer = result.get<flatbuffers::FlatBufferBuilder>(); auto &buffer = std::get<flatbuffers::FlatBufferBuilder>(result);
current_reply.content.resize(buffer.GetSize()); current_reply.content.resize(buffer.GetSize());
std::copy(buffer.GetBufferPointer(), std::copy(buffer.GetBufferPointer(),
buffer.GetBufferPointer() + buffer.GetSize(), buffer.GetBufferPointer() + buffer.GetSize(),
@ -59,10 +60,10 @@ void SendResponse(ServiceHandler::ResultT &result, http::reply &current_reply)
} }
else else
{ {
BOOST_ASSERT(result.is<std::string>()); BOOST_ASSERT(std::holds_alternative<std::string>(result));
current_reply.content.resize(result.get<std::string>().size()); current_reply.content.resize(std::get<std::string>(result).size());
std::copy(result.get<std::string>().cbegin(), std::copy(std::get<std::string>(result).cbegin(),
result.get<std::string>().cend(), std::get<std::string>(result).cend(),
current_reply.content.begin()); current_reply.content.begin());
current_reply.headers.emplace_back("Content-Type", "application/x-protobuf"); current_reply.headers.emplace_back("Content-Type", "application/x-protobuf");
@ -127,7 +128,7 @@ void RequestHandler::HandleRequest(const http::request &current_request, http::r
current_reply.status = http::reply::bad_request; current_reply.status = http::reply::bad_request;
result = util::json::Object(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "InvalidUrl"; json_result.values["code"] = "InvalidUrl";
json_result.values["message"] = "URL string malformed close to position " + json_result.values["message"] = "URL string malformed close to position " +
std::to_string(position) + ": \"" + context + "\""; std::to_string(position) + ": \"" + context + "\"";
@ -174,7 +175,7 @@ void RequestHandler::HandleRequest(const http::request &current_request, http::r
current_reply.status = http::reply::bad_request; current_reply.status = http::reply::bad_request;
ServiceHandler::ResultT result = util::json::Object(); ServiceHandler::ResultT result = util::json::Object();
auto &json_result = result.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "DisabledDataset"; json_result.values["code"] = "DisabledDataset";
json_result.values["message"] = e.what(); json_result.values["message"] = e.what();
SendResponse(result, current_reply); SendResponse(result, current_reply);

View File

@ -42,7 +42,7 @@ engine::Status MatchService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result) osrm::engine::api::ResultT &result)
{ {
result = util::json::Object(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(result);
auto query_iterator = query.begin(); auto query_iterator = query.begin();
auto parameters = auto parameters =

View File

@ -36,7 +36,7 @@ engine::Status NearestService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result) osrm::engine::api::ResultT &result)
{ {
result = util::json::Object(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(result);
auto query_iterator = query.begin(); auto query_iterator = query.begin();
auto parameters = auto parameters =

View File

@ -40,7 +40,7 @@ engine::Status RouteService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result) osrm::engine::api::ResultT &result)
{ {
result = util::json::Object(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(result);
auto query_iterator = query.begin(); auto query_iterator = query.begin();
auto parameters = auto parameters =

View File

@ -71,7 +71,7 @@ engine::Status TableService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result) osrm::engine::api::ResultT &result)
{ {
result = util::json::Object(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(result);
auto query_iterator = query.begin(); auto query_iterator = query.begin();
auto parameters = auto parameters =

View File

@ -22,7 +22,7 @@ engine::Status TileService::RunQuery(std::size_t prefix_length,
{ {
const auto position = std::distance(query.begin(), query_iterator); const auto position = std::distance(query.begin(), query_iterator);
result = util::json::Object(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "InvalidQuery"; json_result.values["code"] = "InvalidQuery";
json_result.values["message"] = json_result.values["message"] =
"Query string malformed close to position " + std::to_string(prefix_length + position); "Query string malformed close to position " + std::to_string(prefix_length + position);
@ -33,7 +33,7 @@ engine::Status TileService::RunQuery(std::size_t prefix_length,
if (!parameters->IsValid()) if (!parameters->IsValid())
{ {
result = util::json::Object(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "InvalidOptions"; json_result.values["code"] = "InvalidOptions";
json_result.values["message"] = "Invalid coodinates. Only zoomlevel 12+ is supported"; json_result.values["message"] = "Invalid coodinates. Only zoomlevel 12+ is supported";
return engine::Status::Error; return engine::Status::Error;

View File

@ -42,7 +42,7 @@ engine::Status TripService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result) osrm::engine::api::ResultT &result)
{ {
result = util::json::Object(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(result);
auto query_iterator = query.begin(); auto query_iterator = query.begin();
auto parameters = auto parameters =
@ -51,7 +51,7 @@ engine::Status TripService::RunQuery(std::size_t prefix_length,
{ {
const auto position = std::distance(query.begin(), query_iterator); const auto position = std::distance(query.begin(), query_iterator);
result = util::json::Object(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "InvalidQuery"; json_result.values["code"] = "InvalidQuery";
json_result.values["message"] = json_result.values["message"] =
"Query string malformed close to position " + std::to_string(prefix_length + position); "Query string malformed close to position " + std::to_string(prefix_length + position);

View File

@ -31,7 +31,7 @@ engine::Status ServiceHandler::RunQuery(api::ParsedURL parsed_url,
if (service_iter == service_map.end()) if (service_iter == service_map.end())
{ {
result = util::json::Object(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "InvalidService"; json_result.values["code"] = "InvalidService";
json_result.values["message"] = "Service " + parsed_url.service + " not found!"; json_result.values["message"] = "Service " + parsed_url.service + " not found!";
return engine::Status::Error; return engine::Status::Error;
@ -41,7 +41,7 @@ engine::Status ServiceHandler::RunQuery(api::ParsedURL parsed_url,
if (service->GetVersion() != parsed_url.version) if (service->GetVersion() != parsed_url.version)
{ {
result = util::json::Object(); result = util::json::Object();
auto &json_result = result.get<util::json::Object>(); auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "InvalidVersion"; json_result.values["code"] = "InvalidVersion";
json_result.values["message"] = "Service " + parsed_url.service + " not found!"; json_result.values["message"] = "Service " + parsed_url.service + " not found!";
return engine::Status::Error; return engine::Status::Error;

View File

@ -61,7 +61,7 @@ std::istream &operator>>(std::istream &in, EngineConfig::Algorithm &algorithm)
in >> token; in >> token;
boost::to_lower(token); boost::to_lower(token);
if (token == "ch" || token == "corech") if (token == "ch")
algorithm = EngineConfig::Algorithm::CH; algorithm = EngineConfig::Algorithm::CH;
else if (token == "mld") else if (token == "mld")
algorithm = EngineConfig::Algorithm::MLD; algorithm = EngineConfig::Algorithm::MLD;
@ -159,7 +159,7 @@ inline unsigned generateServerProgramOptions(const int argc,
("algorithm,a", ("algorithm,a",
value<EngineConfig::Algorithm>(&config.algorithm) value<EngineConfig::Algorithm>(&config.algorithm)
->default_value(EngineConfig::Algorithm::CH, "CH"), ->default_value(EngineConfig::Algorithm::CH, "CH"),
"Algorithm to use for the data. Can be CH, CoreCH, MLD.") // "Algorithm to use for the data. Can be CH, MLD.") //
("disable-feature-dataset", ("disable-feature-dataset",
value<std::vector<storage::FeatureDataset>>(&config.disable_feature_dataset)->multitoken(), value<std::vector<storage::FeatureDataset>>(&config.disable_feature_dataset)->multitoken(),
"Disables a feature dataset from being loaded into memory if not needed. Options: " "Disables a feature dataset from being loaded into memory if not needed. Options: "

View File

@ -146,7 +146,6 @@ double bearing(const Coordinate coordinate_1, const Coordinate coordinate_2)
double computeAngle(const Coordinate first, const Coordinate second, const Coordinate third) double computeAngle(const Coordinate first, const Coordinate second, const Coordinate third)
{ {
using namespace boost::math::constants;
using namespace coordinate_calculation; using namespace coordinate_calculation;
if (first == second || second == third) if (first == second || second == third)
@ -163,7 +162,7 @@ double computeAngle(const Coordinate first, const Coordinate second, const Coord
const double v2y = const double v2y =
web_mercator::latToY(toFloating(third.lat)) - web_mercator::latToY(toFloating(second.lat)); web_mercator::latToY(toFloating(third.lat)) - web_mercator::latToY(toFloating(second.lat));
double angle = (atan2_lookup(v2y, v2x) - atan2_lookup(v1y, v1x)) * 180. / pi<double>(); double angle = (atan2_lookup(v2y, v2x) - atan2_lookup(v1y, v1x)) * 180. * std::numbers::inv_pi;
while (angle < 0.) while (angle < 0.)
{ {

View File

@ -66,4 +66,4 @@ CoordinateVectorToLineString::operator()(const std::vector<util::Coordinate> &in
return makeFeature("LineString", std::move(coordinates), properties); return makeFeature("LineString", std::move(coordinates), properties);
} }
} // namespace osrm::util } // namespace osrm::util

View File

@ -14,20 +14,16 @@ PROFILE:=$(PROFILE_ROOT)/car.lua
all: data all: data
data: ch/$(DATA_NAME).osrm.hsgr corech/$(DATA_NAME).osrm.hsgr mld/$(DATA_NAME).osrm.partition data: ch/$(DATA_NAME).osrm.hsgr mld/$(DATA_NAME).osrm.partition
clean: clean:
-rm -r $(DATA_NAME).* -rm -r $(DATA_NAME).*
-rm -r ch corech mld -rm -r ch mld
ch/$(DATA_NAME).osrm: $(DATA_NAME).osrm ch/$(DATA_NAME).osrm: $(DATA_NAME).osrm
mkdir -p ch mkdir -p ch
cp $(DATA_NAME).osrm.* ch/ cp $(DATA_NAME).osrm.* ch/
corech/$(DATA_NAME).osrm: $(DATA_NAME).osrm
mkdir -p corech
cp $(DATA_NAME).osrm.* corech/
mld/$(DATA_NAME).osrm: $(DATA_NAME).osrm mld/$(DATA_NAME).osrm: $(DATA_NAME).osrm
mkdir -p mld mkdir -p mld
cp $(DATA_NAME).osrm.* mld/ cp $(DATA_NAME).osrm.* mld/
@ -42,10 +38,6 @@ ch/$(DATA_NAME).osrm.hsgr: ch/$(DATA_NAME).osrm $(PROFILE) $(OSRM_CONTRACT)
@echo "Running osrm-contract..." @echo "Running osrm-contract..."
$(TIMER) "osrm-contract\t$@" $(OSRM_CONTRACT) $< $(TIMER) "osrm-contract\t$@" $(OSRM_CONTRACT) $<
corech/$(DATA_NAME).osrm.hsgr: corech/$(DATA_NAME).osrm $(PROFILE) $(OSRM_CONTRACT)
@echo "Running osrm-contract..."
$(TIMER) "osrm-contract\t$@" $(OSRM_CONTRACT) --core=0.5 $<
mld/$(DATA_NAME).osrm.partition: mld/$(DATA_NAME).osrm $(PROFILE) $(OSRM_PARTITION) mld/$(DATA_NAME).osrm.partition: mld/$(DATA_NAME).osrm $(PROFILE) $(OSRM_PARTITION)
@echo "Running osrm-partition..." @echo "Running osrm-partition..."
$(TIMER) "osrm-partition\t$@" $(OSRM_PARTITION) $< $(TIMER) "osrm-partition\t$@" $(OSRM_PARTITION) $<
@ -61,11 +53,6 @@ benchmark: data $(DATA_NAME).requests
$(TIMER) "queries\tCH" "cat $(DATA_NAME).requests | xargs curl &> /dev/null" $(TIMER) "queries\tCH" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
@cat osrm-routed.pid | xargs kill @cat osrm-routed.pid | xargs kill
@rm osrm-routed.pid @rm osrm-routed.pid
@/bin/sh -c '$(OSRM_ROUTED) --algorithm=CoreCH corech/$(DATA_NAME).osrm > /dev/null & echo "$$!" > osrm-routed.pid'
@sleep 1
$(TIMER) "queries\tCoreCH" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
@cat osrm-routed.pid | xargs kill
@rm osrm-routed.pid
@/bin/sh -c '$(OSRM_ROUTED) --algorithm=MLD mld/$(DATA_NAME).osrm > /dev/null & echo "$$!" > osrm-routed.pid' @/bin/sh -c '$(OSRM_ROUTED) --algorithm=MLD mld/$(DATA_NAME).osrm > /dev/null & echo "$$!" > osrm-routed.pid'
@sleep 1 @sleep 1
$(TIMER) "queries\tMLD" "cat $(DATA_NAME).requests | xargs curl &> /dev/null" $(TIMER) "queries\tMLD" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"

Binary file not shown.

Binary file not shown.

View File

@ -16,12 +16,10 @@ exports.test_tile = {'at': [17059, 11948, 15], 'size': 159125};
if (process.env.OSRM_DATA_PATH !== undefined) { if (process.env.OSRM_DATA_PATH !== undefined) {
exports.data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "ch/monaco.osrm"); exports.data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "ch/monaco.osrm");
exports.mld_data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "mld/monaco.osrm"); exports.mld_data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "mld/monaco.osrm");
exports.corech_data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "corech/monaco.osrm");
exports.test_memory_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "test_memory"); exports.test_memory_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "test_memory");
console.log('Setting custom data path to ' + exports.data_path); console.log('Setting custom data path to ' + exports.data_path);
} else { } else {
exports.data_path = path.resolve(path.join(__dirname, "../data/ch/monaco.osrm")); exports.data_path = path.resolve(path.join(__dirname, "../data/ch/monaco.osrm"));
exports.mld_data_path = path.resolve(path.join(__dirname, "../data/mld/monaco.osrm")); exports.mld_data_path = path.resolve(path.join(__dirname, "../data/mld/monaco.osrm"));
exports.corech_data_path = path.resolve(path.join(__dirname, "../data/corech/monaco.osrm"));
exports.test_memory_path = path.resolve(path.join(__dirname, "../data/test_memory")); exports.test_memory_path = path.resolve(path.join(__dirname, "../data/test_memory"));
} }

View File

@ -3,7 +3,6 @@ var test = require('tape');
var monaco_path = require('./constants').data_path; var monaco_path = require('./constants').data_path;
var test_memory_file = require('./constants').test_memory_file; var test_memory_file = require('./constants').test_memory_file;
var monaco_mld_path = require('./constants').mld_data_path; var monaco_mld_path = require('./constants').mld_data_path;
var monaco_corech_path = require('./constants').corech_data_path;
test('constructor: throws if new keyword is not used', function(assert) { test('constructor: throws if new keyword is not used', function(assert) {
assert.plan(1); assert.plan(1);
@ -65,13 +64,13 @@ test('constructor: throws if given a non-string/obj argument', function(assert)
test('constructor: throws if given an unkown algorithm', function(assert) { test('constructor: throws if given an unkown algorithm', function(assert) {
assert.plan(1); assert.plan(1);
assert.throws(function() { new OSRM({algorithm: 'Foo', shared_memory: true}); }, assert.throws(function() { new OSRM({algorithm: 'Foo', shared_memory: true}); },
/algorithm option must be one of 'CH', 'CoreCH', or 'MLD'/); /algorithm option must be one of 'CH', or 'MLD'/);
}); });
test('constructor: throws if given an invalid algorithm', function(assert) { test('constructor: throws if given an invalid algorithm', function(assert) {
assert.plan(1); assert.plan(1);
assert.throws(function() { new OSRM({algorithm: 3, shared_memory: true}); }, assert.throws(function() { new OSRM({algorithm: 3, shared_memory: true}); },
/algorithm option must be a string and one of 'CH', 'CoreCH', or 'MLD'/); /algorithm option must be a string and one of 'CH', or 'MLD'/);
}); });
test('constructor: loads MLD if given as algorithm', function(assert) { test('constructor: loads MLD if given as algorithm', function(assert) {
@ -86,22 +85,8 @@ test('constructor: loads CH if given as algorithm', function(assert) {
assert.ok(osrm); assert.ok(osrm);
}); });
test('constructor: loads CoreCH if given as algorithm', function(assert) {
assert.plan(1);
var osrm = new OSRM({algorithm: 'CoreCH', path: monaco_corech_path});
assert.ok(osrm);
});
test('constructor: autoswitches to CoreCH for a CH dataset if capable', function(assert) {
assert.plan(1);
var osrm = new OSRM({algorithm: 'CH', path: monaco_corech_path});
assert.ok(osrm);
});
test('constructor: throws if data doesn\'t match algorithm', function(assert) { test('constructor: throws if data doesn\'t match algorithm', function(assert) {
assert.plan(3); assert.plan(1);
assert.throws(function() { new OSRM({algorithm: 'CoreCH', path: monaco_mld_path}); }, /Could not find any metrics for CH/, 'CoreCH with MLD data');
assert.ok(new OSRM({algorithm: 'CoreCH', path: monaco_path}), 'CoreCH with CH data');
assert.throws(function() { new OSRM({algorithm: 'MLD', path: monaco_path}); }, /Could not find any metrics for MLD/, 'MLD with CH data'); assert.throws(function() { new OSRM({algorithm: 'MLD', path: monaco_path}); }, /Could not find any metrics for MLD/, 'MLD with CH data');
}); });

View File

@ -2,7 +2,6 @@ var OSRM = require('../../');
var test = require('tape'); var test = require('tape');
var monaco_path = require('./constants').data_path; var monaco_path = require('./constants').data_path;
var monaco_mld_path = require('./constants').mld_data_path; var monaco_mld_path = require('./constants').mld_data_path;
var monaco_corech_path = require('./constants').corech_data_path;
var three_test_coordinates = require('./constants').three_test_coordinates; var three_test_coordinates = require('./constants').three_test_coordinates;
var two_test_coordinates = require('./constants').two_test_coordinates; var two_test_coordinates = require('./constants').two_test_coordinates;
const flatbuffers = require('../../features/support/flatbuffers').flatbuffers; const flatbuffers = require('../../features/support/flatbuffers').flatbuffers;
@ -76,32 +75,6 @@ test('route: routes Monaco on MLD', function(assert) {
}); });
}); });
test('route: routes Monaco on CoreCH', function(assert) {
assert.plan(5);
var osrm = new OSRM({path: monaco_corech_path, algorithm: 'CoreCH'});
osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, function(err, route) {
assert.ifError(err);
assert.ok(route.waypoints);
assert.ok(route.routes);
assert.ok(route.routes.length);
assert.ok(route.routes[0].geometry);
});
});
test('route: routes Monaco and returns a JSON buffer', function(assert) {
assert.plan(6);
var osrm = new OSRM({path: monaco_corech_path, algorithm: 'CoreCH'});
osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, { format: 'json_buffer'}, function(err, result) {
assert.ifError(err);
assert.ok(result instanceof Buffer);
const route = JSON.parse(result);
assert.ok(route.waypoints);
assert.ok(route.routes);
assert.ok(route.routes.length);
assert.ok(route.routes[0].geometry);
});
});
test('route: throws with too few or invalid args', function(assert) { test('route: throws with too few or invalid args', function(assert) {
assert.plan(4); assert.plan(4);
var osrm = new OSRM(monaco_path); var osrm = new OSRM(monaco_path);

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