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-sizeof-expression,
-bugprone-throw-keyword-missing,
-bugprone-chained-comparison,
-bugprone-incorrect-enable-if,
-bugprone-switch-missing-default-case,
-bugprone-empty-catch,
-clang-analyzer-*,
-clang-diagnostic-deprecated-declarations,
-clang-diagnostic-constant-conversion,
@ -49,12 +53,13 @@ Checks: >
-misc-misplaced-const,
-misc-definitions-in-headers,
-misc-unused-parameters,
-misc-include-cleaner,
modernize-concat-nested-namespaces,
modernize-use-using,
performance-*,
-performance-noexcept-move-constructor,
-performance-no-int-to-ptr,
-performance-type-promotion-in-math-fn,
-performance-enum-size,
-performance-avoid-endl,
readability-*,
-readability-avoid-const-params-in-decls,
-readability-braces-around-statements,
@ -83,7 +88,10 @@ Checks: >
-readability-make-member-function-const,
-readability-redundant-string-init,
-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
WarningsAsErrors: '*'

View File

@ -15,7 +15,6 @@ env:
CCACHE_TEMPDIR: /tmp/.ccache-temp
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
CCACHE_VERSION: 3.3.1
CMAKE_VERSION: 3.21.2
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
- run: npm install --ignore-scripts
- run: npm link --ignore-scripts
- uses: microsoft/setup-msbuild@v2
- name: Build
run: |
.\scripts\ci\windows-build.bat
- name: Run node tests
shell: bash
run: |
./lib/binding/osrm-datastore.exe test/data/ch/monaco.osrm
node test/nodejs/index.js
mkdir build
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
shell: bash
run: ./scripts/ci/node_package.sh
@ -193,17 +209,18 @@ jobs:
CXXCOMPILER: clang++-15
CUCUMBER_TIMEOUT: 60000
- name: clang-15-debug-clang-tidy
- name: clang-18-debug-clang-tidy
continue-on-error: false
node: 18
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
BUILD_TOOLS: ON
BUILD_TYPE: Debug
CCOMPILER: clang-15
CXXCOMPILER: clang++-15
CCOMPILER: clang-18
CXXCOMPILER: clang++-18
CUCUMBER_TIMEOUT: 60000
ENABLE_CLANG_TIDY: ON
- name: clang-14-release
continue-on-error: false
node: 18
@ -245,6 +262,16 @@ jobs:
CXXCOMPILER: clang++-15
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
continue-on-error: false
node: 20
@ -265,15 +292,6 @@ jobs:
CXXCOMPILER: g++-12
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
build_node_package: true
continue-on-error: false
@ -377,9 +395,11 @@ jobs:
key: v4-test-${{ matrix.name }}-${{ github.sha }}
restore-keys: |
v4-test-${{ matrix.name }}-
- name: Prepare environment
run: |
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
mkdir -p $HOME/.ccache
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 "OSRM_INSTALL_DIR=${GITHUB_WORKSPACE}/install-osrm" >> $GITHUB_ENV
@ -456,7 +476,7 @@ jobs:
fi
# TBB
TBB_VERSION=2021.3.0
TBB_VERSION=2021.12.0
if [[ "${RUNNER_OS}" == "Linux" ]]; then
TBB_URL="https://github.com/oneapi-src/oneTBB/releases/download/v${TBB_VERSION}/oneapi-tbb-${TBB_VERSION}-lin.tgz"
elif [[ "${RUNNER_OS}" == "macOS" ]]; then
@ -487,8 +507,8 @@ jobs:
run: |
echo "Using ${JOBS} jobs"
pushd ${OSRM_BUILD_DIR}
ccache --zero-stats
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_CONAN=${ENABLE_CONAN:-OFF} \
-DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS:-OFF} \
@ -505,7 +525,7 @@ jobs:
if [[ "${NODE_PACKAGE_TESTS_ONLY}" != "ON" ]]; then
make tests --jobs=${JOBS}
make benchmarks --jobs=${JOBS}
ccache -s
sudo make install
if [[ "${RUNNER_OS}" == "Linux" ]]; then
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${OSRM_INSTALL_DIR}/lib" >> $GITHUB_ENV
@ -608,7 +628,10 @@ jobs:
omitNameDuringUpdate: true
replacesArtifacts: true
token: ${{ secrets.GITHUB_TOKEN }}
- name: Show CCache statistics
run: |
ccache -p
ccache -s
benchmarks:
if: github.event_name == 'pull_request'
@ -622,7 +645,16 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
GITHUB_REPOSITORY: ${{ github.repository }}
RUN_BIG_BENCHMARK: ${{ contains(github.event.pull_request.labels.*.name, 'Performance') }}
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
uses: actions/cache@v4
with:
@ -642,7 +674,30 @@ jobs:
with:
ref: ${{ github.head_ref }}
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
run: |
mkdir -p pr/build
@ -672,6 +727,10 @@ jobs:
- name: Post Benchmark Results
run: |
python3 pr/scripts/ci/post_benchmark_results.py base_results pr_results
- name: Show CCache statistics
run: |
ccache -p
ccache -s
ci-complete:
runs-on: ubuntu-22.04

View File

@ -1,12 +1,15 @@
# Unreleased
- Changes from 5.27.1
- Features
- REMOVED: Remove all core-CH left-overs [#6920](https://github.com/Project-OSRM/osrm-backend/pull/6920)
- ADDED: Add support for a keepalive_timeout flag. [#6674](https://github.com/Project-OSRM/osrm-backend/pull/6674)
- ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575)
- ADDED: Add support for disabling feature datasets. [#6666](https://github.com/Project-OSRM/osrm-backend/pull/6666)
- ADDED: Add support for opposite approach request parameter. [#6842](https://github.com/Project-OSRM/osrm-backend/pull/6842)
- ADDED: Add support for accessing edge flags in `process_segment` [#6658](https://github.com/Project-OSRM/osrm-backend/pull/6658)
- Build:
- CHANGED: Upgrade clang-format to version 15. [#6919](https://github.com/Project-OSRM/osrm-backend/pull/6919)
- CHANGED: Use Debian Bookworm as base Docker image [#6904](https://github.com/Project-OSRM/osrm-backend/pull/6904)
- CHANGED: Upgrade CI actions to latest versions [#6893](https://github.com/Project-OSRM/osrm-backend/pull/6893)
- CHANGED: Remove outdated warnings #6894 [#6894](https://github.com/Project-OSRM/osrm-backend/pull/6894)
- ADDED: Add CI job which builds OSRM with gcc 12. [#6455](https://github.com/Project-OSRM/osrm-backend/pull/6455)
@ -21,6 +24,15 @@
- NodeJS:
- CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452)
- 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: 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)

View File

@ -120,8 +120,7 @@ endif()
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_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/variant/include)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sol2/include)
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(-D_CRT_SECURE_NO_WARNINGS)
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(-DXML_STATIC)
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)
endif()
file(GLOB VariantGlob third_party/variant/include/mapbox/*.hpp)
file(GLOB FlatbuffersGlob third_party/flatbuffers/include/flatbuffers/*.h)
file(GLOB LibraryGlob include/osrm/*.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 ${ParametersGlob} 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(TARGETS osrm-extract 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)
elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930)
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)
else()
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 BUILD_CONCURRENCY
RUN mkdir -p /src && mkdir -p /opt
RUN apt-get update && \
apt-get -y --no-install-recommends install ca-certificates cmake make git gcc g++ libbz2-dev libxml2-dev wget \
libzip-dev libboost1.74-all-dev lua5.4 liblua5.4-dev pkg-config -o APT::Install-Suggests=0 -o APT::Install-Recommends=0
libzip-dev libboost1.81-all-dev lua5.4 liblua5.4-dev pkg-config -o APT::Install-Suggests=0 -o APT::Install-Recommends=0
RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
ldconfig /usr/local/lib && \
git clone --branch v2021.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 && \
mkdir build && \
cd build && \
@ -21,6 +21,7 @@ COPY . /src
WORKDIR /src
RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
export CXXFLAGS="-Wno-array-bounds -Wno-uninitialized" && \
echo "Building OSRM ${DOCKER_TAG}" && \
git show --format="%H" | head -n1 > /opt/OSRM_GITSHA && \
echo "Building OSRM gitsha $(cat /opt/OSRM_GITSHA)" && \
@ -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
# 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 /opt /opt
RUN apt-get update && \
apt-get install -y --no-install-recommends libboost-program-options1.74.0 libboost-regex1.74.0 \
libboost-date-time1.74.0 libboost-chrono1.74.0 libboost-filesystem1.74.0 \
libboost-iostreams1.74.0 libboost-system1.74.0 libboost-thread1.74.0 \
apt-get install -y --no-install-recommends libboost-program-options1.81.0 libboost-regex1.81.0 \
libboost-date-time1.81.0 libboost-chrono1.81.0 libboost-filesystem1.81.0 \
libboost-iostreams1.81.0 libboost-system1.81.0 libboost-thread1.81.0 \
expat liblua5.4-0 && \
rm -rf /var/lib/apt/lists/* && \
# add /usr/local/lib to ldconfig to allow loading libraries from there

View File

@ -21,7 +21,7 @@ var osrm = new OSRM('network.osrm');
**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.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.
- `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.

View File

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

View File

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

View File

@ -41,7 +41,7 @@ inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection
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
@ -79,7 +79,7 @@ util::json::Object makeGeoJSONGeometry(ForwardIter begin, ForwardIter end)
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;
}

View File

@ -30,14 +30,14 @@ class MatchAPI final : public RouteAPI
osrm::engine::api::ResultT &response) const
{
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);
}
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);
}
}

View File

@ -29,14 +29,14 @@ class NearestAPI final : public BaseAPI
BOOST_ASSERT(phantom_nodes.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);
}
else
{
auto &json_result = response.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(response);
MakeResponse(phantom_nodes, json_result);
}
}

View File

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

View File

@ -50,14 +50,14 @@ class TableAPI final : public BaseAPI
const std::vector<TableCellRef> &fallback_speed_cells,
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);
}
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);
}
}
@ -377,7 +377,8 @@ class TableAPI final : public BaseAPI
return util::json::Value(
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;
}
@ -406,7 +407,7 @@ class TableAPI final : public BaseAPI
return util::json::Value(util::json::Number(
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;
}
@ -415,15 +416,18 @@ class TableAPI final : public BaseAPI
MakeEstimatesTable(const std::vector<TableCellRef> &fallback_speed_cells) const
{
util::json::Array json_table;
std::for_each(fallback_speed_cells.begin(),
fallback_speed_cells.end(),
[&](const auto &cell)
{
util::json::Array row;
row.values.push_back(util::json::Number(cell.row));
row.values.push_back(util::json::Number(cell.column));
json_table.values.push_back(std::move(row));
});
std::for_each(
fallback_speed_cells.begin(),
fallback_speed_cells.end(),
[&](const auto &cell)
{
util::json::Array row;
util::json::Value jCellRow{util::json::Number(static_cast<double>(cell.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;
}

View File

@ -27,14 +27,14 @@ class TripAPI final : public RouteAPI
{
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);
}
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);
}
}

View File

@ -54,14 +54,10 @@ namespace osrm::engine
*
* 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
* Contraction Hierarchies, extremely fast queries but slow pre-processing. The default right
* now.
* - Algorithm::CoreCH
* Deprecated, to be removed in v6.0
* Contraction Hierachies with partial contraction for faster pre-processing but slower
* queries.
* - Algorithm::MLD
* Multi Level Dijkstra, moderately fast in both pre-processing and query.
*
@ -74,7 +70,6 @@ struct EngineConfig final
enum class Algorithm
{
CH,
CoreCH, // Deprecated, will be removed in v6.0
MLD
};

View File

@ -6,7 +6,7 @@
#include <utility>
#include <vector>
#include <boost/math/constants/constants.hpp>
#include <numbers>
namespace osrm::engine::map_matching
{
@ -21,10 +21,8 @@ struct NormalDistribution
// FIXME implement log-probability version since it's faster
double Density(const double val) const
{
using namespace boost::math::constants;
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));
}

View File

@ -4,7 +4,7 @@
#include "util/integer_range.hpp"
#include <boost/assert.hpp>
#include <boost/math/constants/constants.hpp>
#include <numbers>
#include <cmath>
@ -14,7 +14,7 @@
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 MINIMAL_LOG_PROB = std::numeric_limits<double>::lowest();
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
#include "engine/map_matching/bayes_classifier.hpp"
#include <boost/assert.hpp>
#include <cmath>
namespace osrm::engine::map_matching

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,18 +17,18 @@ struct TrafficSignals
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)
{
bidirectional_nodes.erase(via);
if (unidirectional_segments.count({via, to}))
if (unidirectional_segments.contains({via, to}))
{
unidirectional_segments.erase({via, 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.insert({to, from});

View File

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

View File

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

View File

@ -28,6 +28,7 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <variant>
#include <vector>
#include <exception>
@ -50,7 +51,7 @@ struct PluginParameters
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);
@ -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)
{
if (result.is<osrm::json::Object>())
if (std::holds_alternative<osrm::json::Object>(result))
{
// Convert osrm::json object tree into matching v8 object tree
Napi::Value value;
renderToV8(env, value, result.get<osrm::json::Object>());
renderToV8(env, value, std::get<osrm::json::Object>(result));
return value;
}
else
{
// Return the string object as a node Buffer
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)
{
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);
@ -295,24 +296,19 @@ inline engine_config_ptr argumentsToEngineConfig(const Napi::CallbackInfo &args)
{
engine_config->algorithm = osrm::EngineConfig::Algorithm::CH;
}
else if (algorithm_str == "CoreCH")
{
engine_config->algorithm = osrm::EngineConfig::Algorithm::CH;
}
else if (algorithm_str == "MLD")
{
engine_config->algorithm = osrm::EngineConfig::Algorithm::MLD;
}
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();
}
}
else if (!algorithm.IsUndefined())
{
ThrowError(args.Env(),
"algorithm option must be a string and one of 'CH', 'CoreCH', or 'MLD'.");
ThrowError(args.Env(), "algorithm option must be a string and one of 'CH', or 'MLD'.");
return engine_config_ptr();
}

View File

@ -12,7 +12,7 @@ struct header
// explicitly use default copy c'tor as adding move c'tor
header &operator=(const header &other) = default;
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()
{

View File

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

View File

@ -61,7 +61,7 @@ class SharedMemory
{
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);
}

View File

@ -4,6 +4,7 @@
#include <cmath>
#include <cstdint>
#include <limits>
#include <numbers>
#include <tuple>
#include <utility>
@ -37,7 +38,7 @@ class CheapRuler
static constexpr double FE = 1.0 / 298.257223563; // flattening
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:
explicit CheapRuler(double latitude)

View File

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

View File

@ -3,7 +3,7 @@
#include "util/coordinate.hpp"
#include <boost/math/constants/constants.hpp>
#include <numbers>
#include <algorithm>
#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)
const constexpr long double EARTH_RADIUS = 6372797.560856;
inline double degToRad(const double degree)
{
using namespace boost::math::constants;
return degree * (pi<double>() / 180.0);
}
inline double degToRad(const double degree) { return degree * (std::numbers::pi / 180.0); }
inline double radToDeg(const double radian)
{
using namespace boost::math::constants;
return radian * (180.0 * (1. / pi<double>()));
}
inline double radToDeg(const double radian) { return radian * (180.0 * std::numbers::inv_pi); }
} // namespace detail
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 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
{
@ -204,8 +204,8 @@ template <typename ElementT> class DeallocatingVector
}
// moving is fine
DeallocatingVector(DeallocatingVector &&other) { swap(other); }
DeallocatingVector &operator=(DeallocatingVector &&other)
DeallocatingVector(DeallocatingVector &&other) noexcept { swap(other); }
DeallocatingVector &operator=(DeallocatingVector &&other) noexcept
{
swap(other);
return *this;
@ -221,9 +221,10 @@ template <typename ElementT> class DeallocatingVector
~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);
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);
}

View File

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

View File

@ -51,7 +51,7 @@ class GeojsonLogger
if (!first)
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;
}

View File

@ -51,4 +51,4 @@ struct CoordinateVectorToMultiPoint
} // 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
{
util::json::Array operator()(const util::Coordinate coordinate)
util::json::Value operator()(const util::Coordinate 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.lat)));
return json_coordinate;
return util::json::Value{json_coordinate};
}
};
@ -73,7 +73,7 @@ struct NodeIdToCoordinate
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];
CoordinateToJsonArray converter;
@ -108,4 +108,4 @@ inline util::json::Array makeJsonArray(const std::vector<util::Coordinate> &inpu
}
} // 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 <boost/algorithm/string.hpp>
#include <algorithm>
#include <string>
#include <tuple>
@ -126,8 +124,7 @@ inline bool requiresNameAnnounced(const StringView &from_name,
// check similarity of names
const auto names_are_empty = from_name.empty() && to_name.empty();
const auto name_is_contained =
boost::starts_with(from_name, to_name) || boost::starts_with(to_name, from_name);
const auto name_is_contained = from_name.starts_with(to_name) || to_name.starts_with(from_name);
const auto checkForPrefixOrSuffixChange = [](const std::string_view first,
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
#define JSON_CONTAINER_HPP
#include <mapbox/variant.hpp>
#include <string>
#include <unordered_map>
#include <utility>
#include <variant>
#include <vector>
namespace osrm::util::json
@ -96,13 +95,7 @@ struct Null
*
* Dispatch on its type by either by using apply_visitor or its get function.
*/
using Value = mapbox::util::variant<String,
Number,
mapbox::util::recursive_wrapper<Object>,
mapbox::util::recursive_wrapper<Array>,
True,
False,
Null>;
using Value = std::variant<String, Number, Object, Array, True, False, Null>;
/**
* Typed Object.

View File

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

View File

@ -67,7 +67,7 @@ template <typename Out> struct Renderer
write('\"');
write(it->first);
write<>("\":");
mapbox::util::apply_visitor(Renderer(out), it->second);
std::visit(Renderer(out), it->second);
if (++it != end)
{
write(',');
@ -81,7 +81,7 @@ template <typename Out> struct Renderer
write('[');
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)
{
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
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;
@ -170,7 +169,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
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;
@ -194,7 +193,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
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;
@ -209,7 +208,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
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;
@ -232,7 +231,7 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
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;
@ -246,28 +245,15 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
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
// 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>
upper_mask /* = initialize_upper_mask()*/;
/* static constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS>
lower_offset /* = initialize_lower_offset()*/;
/* static constexpr */ std::array<std::uint8_t, BLOCK_ELEMENTS>
upper_offset /* = initialize_upper_offset()*/;
static constexpr std::array<WordT, BLOCK_ELEMENTS> lower_mask = initialize_lower_mask();
static constexpr std::array<WordT, BLOCK_ELEMENTS> upper_mask = initialize_upper_mask();
static constexpr std::array<std::uint8_t, BLOCK_ELEMENTS> 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
/* 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();
struct InternalIndex
@ -378,27 +364,21 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
PackedVector(std::initializer_list<T> list)
{
initialize();
reserve(list.size());
for (const auto value : list)
push_back(value);
}
PackedVector() { initialize(); };
PackedVector(){};
PackedVector(const PackedVector &) = default;
PackedVector(PackedVector &&) = default;
PackedVector &operator=(const PackedVector &) = default;
PackedVector &operator=(PackedVector &&) = default;
PackedVector(std::size_t size)
{
initialize();
resize(size);
}
PackedVector(std::size_t size) { resize(size); }
PackedVector(std::size_t size, T initial_value)
{
initialize();
resize(size);
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)
: vec(std::move(vec_)), num_elements(num_elements)
{
initialize();
}
// forces the efficient read-only lookup

View File

@ -10,9 +10,9 @@ namespace osrm::util
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);
}

View File

@ -193,7 +193,20 @@ template <typename NodeID,
class QueryHeap
{
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,
boost::heap::arity<4>,
boost::heap::mutable_<true>,
@ -232,7 +245,7 @@ class QueryHeap
{
BOOST_ASSERT(node < std::numeric_limits<NodeID>::max());
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});
node_index[node] = index;
}
@ -315,19 +328,19 @@ class QueryHeap
NodeID Min() const
{
BOOST_ASSERT(!heap.empty());
return inserted_nodes[heap.top().second].node;
return inserted_nodes[heap.top().index].node;
}
Weight MinKey() const
{
BOOST_ASSERT(!heap.empty());
return heap.top().first;
return heap.top().weight;
}
NodeID DeleteMin()
{
BOOST_ASSERT(!heap.empty());
const Key removedIndex = heap.top().second;
const Key removedIndex = heap.top().index;
heap.pop();
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
return inserted_nodes[removedIndex].node;
@ -336,7 +349,7 @@ class QueryHeap
HeapNode &DeleteMinGetHeapNode()
{
BOOST_ASSERT(!heap.empty());
const Key removedIndex = heap.top().second;
const Key removedIndex = heap.top().index;
heap.pop();
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
return inserted_nodes[removedIndex];
@ -357,13 +370,13 @@ class QueryHeap
const auto index = node_index.peek_index(node);
auto &reference = inserted_nodes[index];
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)
{
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:

View File

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

View File

@ -6,7 +6,7 @@
#include <limits>
#include <boost/math/constants/constants.hpp>
#include <numbers>
namespace osrm::util
{
@ -356,25 +356,21 @@ constexpr unsigned short atan_table[4096] = {
0xffe0, 0xffea, 0xfff4, 0xffff};
// 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. / M_PI * 0xFFFF;
#else
const constexpr double SCALING_FACTOR = 4. / boost::math::constants::pi<double>() * 0xFFFF;
#endif
const constexpr double SCALING_FACTOR = 4. * std::numbers::inv_pi * 0xFFFF;
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 (y >= 0.)
{
return half_pi<double>();
return half_pi;
}
else
{
return -half_pi<double>();
return -half_pi;
}
}
@ -405,25 +401,25 @@ inline double atan2_lookup(double y, double x)
case 0:
break;
case 1:
angle = pi<double>() - angle;
angle = std::numbers::pi - angle;
break;
case 2:
angle = -angle;
break;
case 3:
angle = -pi<double>() + angle;
angle = -std::numbers::pi + angle;
break;
case 4:
angle = half_pi<double>() - angle;
angle = half_pi - angle;
break;
case 5:
angle = half_pi<double>() + angle;
angle = half_pi + angle;
break;
case 6:
angle = -half_pi<double>() + angle;
angle = -half_pi + angle;
break;
case 7:
angle = -half_pi<double>() - angle;
angle = -half_pi - angle;
break;
}
return angle;

View File

@ -3,7 +3,7 @@
#include "util/coordinate.hpp"
#include <boost/math/constants/constants.hpp>
#include <numbers>
namespace osrm::util::web_mercator
{
@ -14,7 +14,7 @@ const constexpr double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
// radius used by WGS84
const constexpr double EARTH_RADIUS_WGS84 = 6378137.0;
// 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) :(
const constexpr double EPSG3857_MAX_LATITUDE = 85.051128779806592378; // 90(4*atan(exp(pi))/pi-1)
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;
x = (x - b) / shift * 360.0;
// FIXME needs to be simplified
const double g = (y - b) / -(shift / (2 * M_PI)) / detail::DEGREE_TO_RAD;
static_assert(detail::DEGREE_TO_RAD / (2 * M_PI) - 1 / 360. < 0.0001, "");
const double g = (y - b) / -(shift * 0.5 * std::numbers::inv_pi) / detail::DEGREE_TO_RAD;
static_assert(detail::DEGREE_TO_RAD * 0.5 * std::numbers::inv_pi - 1 / 360. < 0.0001, "");
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 = []
for result in results:
name = result['name']
base = result['base'].replace('\n', '<br/>')
pr = result['pr'].replace('\n', '<br/>')
base = result['base'] or ''
base = base.replace('\n', '<br/>')
pr = result['pr'] or ''
pr = pr.replace('\n', '<br/>')
row = f"| {name} | {base} | {pr} |"
rows.append(row)
return f"{header}\n" + "\n".join(rows)
@ -75,7 +77,14 @@ def main():
pr_body = pr_details.get('body', '') or ''
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):
updated_body = re.sub(

View File

@ -1,11 +1,24 @@
#!/bin/bash
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 {
echo "Running benchmarks for $1"
FOLDER=$1
RESULTS_FOLDER=$2
SCRIPTS_FOLDER=$3
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/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/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/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"
./$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/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"
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 $2 "${2}_results"
run_benchmarks_for_folder $1 "${1}_results" $2
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_TAG=v2.14.0
VARIANT_PATH="mapbox/variant"
VARIANT_TAG=v1.2.0
SOL_PATH="ThePhD/sol2"
SOL_TAG=v2.17.5
SOL_TAG=v3.3.0
RAPIDJSON_PATH="Tencent/rapidjson"
RAPIDJSON_TAG=v1.1.0
RAPIDJSON_TAG=f9d53419e912910fd8fa57d5705fa41425428c35
MICROTAR_PATH="rxi/microtar"
MICROTAR_TAG=v0.1.0
@ -56,6 +53,6 @@ function update_subtree () {
}
## 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
done

View File

@ -18,6 +18,7 @@ target_link_libraries(rtree-bench
${TBB_LIBRARIES}
${MAYBE_SHAPEFILE})
add_executable(match-bench
EXCLUDE_FROM_ALL
${MatchBenchmarkSources}
@ -35,6 +36,7 @@ add_executable(route-bench
route.cpp
$<TARGET_OBJECTS:UTIL>)
target_link_libraries(route-bench
osrm
${BOOST_BASE_LIBRARIES}
@ -42,6 +44,18 @@ target_link_libraries(route-bench
${TBB_LIBRARIES}
${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
EXCLUDE_FROM_ALL
json_render.cpp
@ -85,5 +99,6 @@ add_custom_target(benchmarks
packedvector-bench
match-bench
route-bench
bench
json-render-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;
convert(document, result);
return result.get<json::Object>();
return std::get<json::Object>(result);
}
} // namespace

View File

@ -232,9 +232,9 @@ try
{
engine::api::ResultT result = json::Object();
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 ||
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"};
}

View File

@ -76,7 +76,7 @@ try
{
engine::api::ResultT result = json::Object();
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())
{
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)];
}
util::json::Array coordinateToLonLat(const util::Coordinate &coordinate)
util::json::Value coordinateToLonLat(const util::Coordinate &coordinate)
{
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.lat)));
return array;
return util::json::Value{std::move(array)};
}
} // namespace detail

View File

@ -125,9 +125,9 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
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);
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);
}
@ -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
if (is_straight_left.count(&current) > 0)
if (is_straight_left.contains(&current))
anticipate_for_left_turn();
else if (is_straight_right.count(&current) > 0)
else if (is_straight_right.contains(&current))
anticipate_for_right_turn();
else // FIXME: right-sided driving
anticipate_for_right_turn();

View File

@ -497,13 +497,13 @@ void encodeVectorTile(const DataFacadeBase &facade,
{
// Calculate the speed for this line
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
// present 1 decimal place of precision (these values are added as
// double/10) lower down
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);
if (!tile_line.empty())
@ -531,13 +531,13 @@ void encodeVectorTile(const DataFacadeBase &facade,
{
// Calculate the speed for this line
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
// present 1 decimal place of precision (these values are added as
// double/10) lower down
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);
if (!tile_line.empty())
@ -663,7 +663,7 @@ Status TilePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
{
BOOST_ASSERT(parameters.IsValid());
auto &pbf_buffer = result.get<std::string>();
auto &pbf_buffer = std::get<std::string>(result);
const auto &facade = algorithms.GetFacade();
auto edges = getEdges(facade, parameters.x, parameters.y, parameters.z);
auto segregated_nodes = getSegregatedNodes(facade, edges);

View File

@ -248,7 +248,7 @@ filterViaCandidatesByViaNotOnPath(const WeightedViaNodePackedPath &path, RandIt
for (const auto &edge : path.path)
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);
}
@ -308,7 +308,7 @@ RandIt filterPackedPathsByCellSharing(RandIt first,
{
const auto source_cell = get_cell(std::get<0>(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);
@ -491,7 +491,7 @@ RandIt filterUnpackedPathsBySharing(RandIt first,
{
auto node_duration = facade.GetNodeDuration(node);
total_duration += node_duration;
if (nodes.count(node) > 0)
if (nodes.contains(node))
{
return duration + node_duration;
}

View File

@ -325,7 +325,7 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
EdgeDuration initial_duration,
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
// 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.
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)};
}
@ -64,7 +64,7 @@ std::vector<TurnData> generateTurns(const datafacade &facade,
if (edge.reverse_segment_id.enabled)
{
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)};
}
@ -106,7 +106,7 @@ std::vector<TurnData> generateTurns(const datafacade &facade,
{
// If the target of this edge doesn't exist in our directed
// 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;
// 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 =
forward_data.annotation_data;
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)
{
@ -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 =
reverse_data.annotation_data;
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
@ -382,7 +382,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
m_edge_based_node_container.nodes[edge_based_node_id].annotation_id =
edge_data.annotation_data;
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]];
BOOST_ASSERT((ebn_weight & EdgeWeight{0x7fffffff}) == edge_data.weight);
@ -942,7 +942,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const auto turn_nodes = NodeBasedTurn{
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)
{

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
if (incompressible_via_nodes.count(node_v) > 0)
if (incompressible_via_nodes.contains(node_v))
{
continue;
}

View File

@ -6,6 +6,7 @@
#include "util/coordinate_calculation.hpp"
#include <boost/optional/optional_io.hpp>
#include <numbers>
namespace osrm::extractor::intersection
{
@ -79,11 +80,11 @@ namespace
{
double findAngleBisector(double alpha, double beta)
{
alpha *= M_PI / 180.;
beta *= M_PI / 180.;
alpha *= std::numbers::pi / 180.;
beta *= std::numbers::pi / 180.;
const auto average =
180. * std::atan2(std::sin(alpha) + std::sin(beta), std::cos(alpha) + std::cos(beta)) /
M_PI;
180. * std::atan2(std::sin(alpha) + std::sin(beta), std::cos(alpha) + std::cos(beta)) *
std::numbers::inv_pi;
return std::fmod(average + 360., 360.);
}
@ -622,7 +623,7 @@ IntersectionView convertToIntersectionView(const util::NodeBasedDynamicGraph &gr
for (const auto &outgoing_edge : outgoing_edges)
{
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,
node_data_container,
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 the left and right roads connect again and are closed polygons ...
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);
// 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)
return true;
}

View File

@ -40,8 +40,8 @@ RasterDatum RasterSource::GetRasterData(const int lon, const int lat) const
return {};
}
const std::size_t xth = static_cast<std::size_t>(round((lon - xmin) / xstep));
const std::size_t yth = static_cast<std::size_t>(round((ymax - lat) / ystep));
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>(std::round((ymax - lat) / ystep));
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
{
return suffix_set.count(possible_suffix) > 0;
return suffix_set.contains(possible_suffix);
}
} // 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
{
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,

View File

@ -302,7 +302,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
if (roundabout == circular)
return RoundaboutType::None;
while (0 == roundabout_nodes.count(last_node))
while (!roundabout_nodes.contains(last_node))
{
// only count exits/entry locations
if (node_based_graph.GetOutDegree(last_node) > 2)
@ -337,7 +337,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
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
// 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
// when we handle references separately or if the useage is more consistent
const auto is_rotary = (1 == roundabout_name_ids.size()) &&
(circular || //
((0 == connected_names.count(*roundabout_name_ids.begin())) && //
(circular || //
((!connected_names.contains(*roundabout_name_ids.begin())) && //
(radius > MAX_ROUNDABOUT_RADIUS)));
if (is_rotary)

View File

@ -508,7 +508,7 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
}();
BOOST_ASSERT(best_match != intersection.end());
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);
// in case of u-turns, we might need to activate them first
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 {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.
* @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.
@ -147,7 +147,7 @@ inline void async(const Napi::CallbackInfo &info,
osrm::engine::api::ResultT r;
r = osrm::util::json::Object();
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);
if (pluginParams.renderToBuffer)
{
@ -165,7 +165,7 @@ inline void async(const Napi::CallbackInfo &info,
{
osrm::engine::api::ResultT r = flatbuffers::FlatBufferBuilder();
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);
BOOST_ASSERT(pluginParams.renderToBuffer);
std::string result_str(
@ -240,7 +240,7 @@ inline void asyncForTiles(const Napi::CallbackInfo &info,
{
result = std::string();
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);
}
catch (const std::exception &e)
@ -252,7 +252,7 @@ inline void asyncForTiles(const Napi::CallbackInfo &info,
{
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

View File

@ -36,13 +36,6 @@ OSRM::OSRM(engine::EngineConfig &config)
// Now, check that the algorithm requested can be used with the data
// 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)
{
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();
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;
}
@ -78,7 +71,7 @@ Status OSRM::Table(const engine::api::TableParameters &params, json::Object &jso
{
osrm::engine::api::ResultT result = json::Object();
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;
}
@ -91,7 +84,7 @@ Status OSRM::Nearest(const engine::api::NearestParameters &params, json::Object
{
osrm::engine::api::ResultT result = json::Object();
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;
}
@ -104,7 +97,7 @@ Status OSRM::Trip(const engine::api::TripParameters &params, json::Object &json_
{
osrm::engine::api::ResultT result = json::Object();
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;
}
@ -118,7 +111,7 @@ Status OSRM::Match(const engine::api::MatchParameters &params, json::Object &jso
{
osrm::engine::api::ResultT result = json::Object();
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;
}
@ -131,7 +124,7 @@ Status OSRM::Tile(const engine::api::TileParameters &params, std::string &str_re
{
osrm::engine::api::ResultT result = std::string();
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;
}

View File

@ -22,7 +22,7 @@ auto makeHasNeighborNotInCheck(const DinicMaxFlow::SourceSinkNodes &set,
return [&](const NodeID nid)
{
const auto is_not_contained = [&set](const BisectionEdge &edge)
{ return set.count(edge.target) == 0; };
{ return !set.contains(edge.target); };
return view.EndEdges(nid) !=
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;
level_queue.push(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;
}
// 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)
{
// don't relax sink nodes
if (sink_nodes.count(node_id))
if (sink_nodes.contains(node_id))
return;
const auto level = levels[node_id] + 1;
@ -264,7 +264,7 @@ std::vector<NodeID> DinicMaxFlow::GetAugmentingPath(LevelGraph &levels,
dfs_stack.top().edge_iterator++;
// 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()];
if (has_capacity && descends_level_graph)
@ -300,8 +300,9 @@ bool DinicMaxFlow::Validate(const BisectionGraphView &view,
// sink and source cannot share a common node
const auto separated = std::find_if(source_nodes.begin(),
source_nodes.end(),
[&sink_nodes](const auto node)
{ return sink_nodes.count(node); }) == source_nodes.end();
[&sink_nodes](const auto node) {
return sink_nodes.contains(node);
}) == source_nodes.end();
const auto invalid_id = [&view](const NodeID nid) { return nid >= view.NumberOfNodes(); };
const auto in_range_source =

View File

@ -15,7 +15,6 @@
#include "util/coordinate.hpp"
#include "util/geojson_debug_logger.hpp"
#include "util/geojson_debug_policies.hpp"
#include "util/integer_range.hpp"
#include "util/json_container.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)
{
boost::system::error_code ignore_error;
// NOLINTNEXTLINE(bugprone-unused-return-value)
TCP_socket.cancel(ignore_error);
handle_shutdown();
}
@ -197,6 +198,7 @@ void Connection::handle_shutdown()
timer.cancel();
// Initiate graceful connection closure.
boost::system::error_code ignore_error;
// NOLINTNEXTLINE(bugprone-unused-return-value)
TCP_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignore_error);
}

View File

@ -21,6 +21,7 @@
#include <algorithm>
#include <string>
#include <thread>
#include <variant>
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-Headers",
"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-Disposition",
"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());
std::copy(buffer.GetBufferPointer(),
buffer.GetBufferPointer() + buffer.GetSize(),
@ -59,10 +60,10 @@ void SendResponse(ServiceHandler::ResultT &result, http::reply &current_reply)
}
else
{
BOOST_ASSERT(result.is<std::string>());
current_reply.content.resize(result.get<std::string>().size());
std::copy(result.get<std::string>().cbegin(),
result.get<std::string>().cend(),
BOOST_ASSERT(std::holds_alternative<std::string>(result));
current_reply.content.resize(std::get<std::string>(result).size());
std::copy(std::get<std::string>(result).cbegin(),
std::get<std::string>(result).cend(),
current_reply.content.begin());
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;
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["message"] = "URL string malformed close to position " +
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;
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["message"] = e.what();
SendResponse(result, current_reply);

View File

@ -42,7 +42,7 @@ engine::Status MatchService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result)
{
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 parameters =

View File

@ -36,7 +36,7 @@ engine::Status NearestService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result)
{
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 parameters =

View File

@ -40,7 +40,7 @@ engine::Status RouteService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result)
{
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 parameters =

View File

@ -71,7 +71,7 @@ engine::Status TableService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result)
{
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 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);
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["message"] =
"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())
{
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["message"] = "Invalid coodinates. Only zoomlevel 12+ is supported";
return engine::Status::Error;

View File

@ -42,7 +42,7 @@ engine::Status TripService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result)
{
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 parameters =
@ -51,7 +51,7 @@ engine::Status TripService::RunQuery(std::size_t prefix_length,
{
const auto position = std::distance(query.begin(), query_iterator);
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["message"] =
"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())
{
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["message"] = "Service " + parsed_url.service + " not found!";
return engine::Status::Error;
@ -41,7 +41,7 @@ engine::Status ServiceHandler::RunQuery(api::ParsedURL parsed_url,
if (service->GetVersion() != parsed_url.version)
{
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["message"] = "Service " + parsed_url.service + " not found!";
return engine::Status::Error;

View File

@ -61,7 +61,7 @@ std::istream &operator>>(std::istream &in, EngineConfig::Algorithm &algorithm)
in >> token;
boost::to_lower(token);
if (token == "ch" || token == "corech")
if (token == "ch")
algorithm = EngineConfig::Algorithm::CH;
else if (token == "mld")
algorithm = EngineConfig::Algorithm::MLD;
@ -159,7 +159,7 @@ inline unsigned generateServerProgramOptions(const int argc,
("algorithm,a",
value<EngineConfig::Algorithm>(&config.algorithm)
->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",
value<std::vector<storage::FeatureDataset>>(&config.disable_feature_dataset)->multitoken(),
"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)
{
using namespace boost::math::constants;
using namespace coordinate_calculation;
if (first == second || second == third)
@ -163,7 +162,7 @@ double computeAngle(const Coordinate first, const Coordinate second, const Coord
const double v2y =
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.)
{

View File

@ -66,4 +66,4 @@ CoordinateVectorToLineString::operator()(const std::vector<util::Coordinate> &in
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
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:
-rm -r $(DATA_NAME).*
-rm -r ch corech mld
-rm -r ch mld
ch/$(DATA_NAME).osrm: $(DATA_NAME).osrm
mkdir -p 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
mkdir -p 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..."
$(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)
@echo "Running 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"
@cat osrm-routed.pid | xargs kill
@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'
@sleep 1
$(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) {
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.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");
console.log('Setting custom data path to ' + exports.data_path);
} else {
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.corech_data_path = path.resolve(path.join(__dirname, "../data/corech/monaco.osrm"));
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 test_memory_file = require('./constants').test_memory_file;
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) {
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) {
assert.plan(1);
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) {
assert.plan(1);
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) {
@ -86,22 +85,8 @@ test('constructor: loads CH if given as algorithm', function(assert) {
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) {
assert.plan(3);
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.plan(1);
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 monaco_path = require('./constants').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 two_test_coordinates = require('./constants').two_test_coordinates;
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) {
assert.plan(4);
var osrm = new OSRM(monaco_path);

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