Merge branch 'master' into sf-ankerl
This commit is contained in:
commit
2e54842ce8
17
.github/workflows/osrm-backend.yml
vendored
17
.github/workflows/osrm-backend.yml
vendored
@ -377,7 +377,6 @@ jobs:
|
|||||||
key: v4-test-${{ matrix.name }}-${{ github.sha }}
|
key: v4-test-${{ matrix.name }}-${{ github.sha }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
v4-test-${{ matrix.name }}-
|
v4-test-${{ matrix.name }}-
|
||||||
|
|
||||||
- name: Prepare environment
|
- name: Prepare environment
|
||||||
run: |
|
run: |
|
||||||
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
|
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
|
||||||
@ -508,6 +507,7 @@ jobs:
|
|||||||
if [[ "${NODE_PACKAGE_TESTS_ONLY}" != "ON" ]]; then
|
if [[ "${NODE_PACKAGE_TESTS_ONLY}" != "ON" ]]; then
|
||||||
make tests --jobs=${JOBS}
|
make tests --jobs=${JOBS}
|
||||||
make benchmarks --jobs=${JOBS}
|
make benchmarks --jobs=${JOBS}
|
||||||
|
|
||||||
sudo make install
|
sudo make install
|
||||||
if [[ "${RUNNER_OS}" == "Linux" ]]; then
|
if [[ "${RUNNER_OS}" == "Linux" ]]; then
|
||||||
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${OSRM_INSTALL_DIR}/lib" >> $GITHUB_ENV
|
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${OSRM_INSTALL_DIR}/lib" >> $GITHUB_ENV
|
||||||
@ -628,6 +628,13 @@ jobs:
|
|||||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||||
steps:
|
steps:
|
||||||
|
- name: Enable data.osm.pbf cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/data.osm.pbf
|
||||||
|
key: v1-data-osm-pbf
|
||||||
|
restore-keys: |
|
||||||
|
v1-data-osm-pbf
|
||||||
- name: Enable compiler cache
|
- name: Enable compiler cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
@ -649,8 +656,14 @@ jobs:
|
|||||||
path: pr
|
path: pr
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python3 -m pip install "conan<2.0.0" "requests==2.31.0"
|
python3 -m pip install "conan<2.0.0" "requests==2.31.0" "locust==2.28.0"
|
||||||
sudo apt-get update -y && sudo apt-get install ccache
|
sudo apt-get update -y && sudo apt-get install ccache
|
||||||
|
- name: Prepare data
|
||||||
|
run: |
|
||||||
|
if [ ! -f "~/data.osm.pbf" ]; then
|
||||||
|
wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf -O ~/data.osm.pbf
|
||||||
|
fi
|
||||||
|
gunzip -c ./pr/test/data/berlin_gps_traces.csv.gz > ~/gps_traces.csv
|
||||||
- name: Prepare environment
|
- name: Prepare environment
|
||||||
run: |
|
run: |
|
||||||
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
|
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Unreleased
|
# Unreleased
|
||||||
- Changes from 5.27.1
|
- Changes from 5.27.1
|
||||||
- Features
|
- Features
|
||||||
|
- REMOVED: Remove all core-CH left-overs [#6920](https://github.com/Project-OSRM/osrm-backend/pull/6920)
|
||||||
- ADDED: Add support for a keepalive_timeout flag. [#6674](https://github.com/Project-OSRM/osrm-backend/pull/6674)
|
- ADDED: Add support for a keepalive_timeout flag. [#6674](https://github.com/Project-OSRM/osrm-backend/pull/6674)
|
||||||
- ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575)
|
- ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575)
|
||||||
- ADDED: Add support for disabling feature datasets. [#6666](https://github.com/Project-OSRM/osrm-backend/pull/6666)
|
- ADDED: Add support for disabling feature datasets. [#6666](https://github.com/Project-OSRM/osrm-backend/pull/6666)
|
||||||
@ -22,6 +23,9 @@
|
|||||||
- NodeJS:
|
- NodeJS:
|
||||||
- CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452)
|
- CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452)
|
||||||
- Misc:
|
- Misc:
|
||||||
|
- CHANGED: 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: 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: 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 rapidjson to version f9d53419e912910fd8fa57d5705fa41425428c35 [#6906](https://github.com/Project-OSRM/osrm-backend/pull/6906)
|
||||||
|
@ -266,7 +266,6 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
|||||||
add_dependency_defines(-DBOOST_LIB_DIAGNOSTIC)
|
add_dependency_defines(-DBOOST_LIB_DIAGNOSTIC)
|
||||||
add_dependency_defines(-D_CRT_SECURE_NO_WARNINGS)
|
add_dependency_defines(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
add_dependency_defines(-DNOMINMAX) # avoid min and max macros that can break compilation
|
add_dependency_defines(-DNOMINMAX) # avoid min and max macros that can break compilation
|
||||||
add_dependency_defines(-D_USE_MATH_DEFINES) #needed for M_PI with cmath.h
|
|
||||||
add_dependency_defines(-D_WIN32_WINNT=0x0501)
|
add_dependency_defines(-D_WIN32_WINNT=0x0501)
|
||||||
add_dependency_defines(-DXML_STATIC)
|
add_dependency_defines(-DXML_STATIC)
|
||||||
find_library(ws2_32_LIBRARY_PATH ws2_32)
|
find_library(ws2_32_LIBRARY_PATH ws2_32)
|
||||||
|
@ -21,7 +21,7 @@ var osrm = new OSRM('network.osrm');
|
|||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- `options` **([Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** Options for creating an OSRM object or string to the `.osrm` file. (optional, default `{shared_memory:true}`)
|
- `options` **([Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** Options for creating an OSRM object or string to the `.osrm` file. (optional, default `{shared_memory:true}`)
|
||||||
- `options.algorithm` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The algorithm to use for routing. Can be 'CH', 'CoreCH' or 'MLD'. Default is 'CH'.
|
- `options.algorithm` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** The algorithm to use for routing. Can be 'CH', or 'MLD'. Default is 'CH'.
|
||||||
Make sure you prepared the dataset with the correct toolchain.
|
Make sure you prepared the dataset with the correct toolchain.
|
||||||
- `options.shared_memory` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore.
|
- `options.shared_memory` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Connects to the persistent shared memory datastore.
|
||||||
This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
|
This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
|
||||||
|
@ -54,14 +54,10 @@ namespace osrm::engine
|
|||||||
*
|
*
|
||||||
* In addition, shared memory can be used for datasets loaded with osrm-datastore.
|
* In addition, shared memory can be used for datasets loaded with osrm-datastore.
|
||||||
*
|
*
|
||||||
* You can chose between three algorithms:
|
* You can chose between two algorithms:
|
||||||
* - Algorithm::CH
|
* - Algorithm::CH
|
||||||
* Contraction Hierarchies, extremely fast queries but slow pre-processing. The default right
|
* Contraction Hierarchies, extremely fast queries but slow pre-processing. The default right
|
||||||
* now.
|
* now.
|
||||||
* - Algorithm::CoreCH
|
|
||||||
* Deprecated, to be removed in v6.0
|
|
||||||
* Contraction Hierachies with partial contraction for faster pre-processing but slower
|
|
||||||
* queries.
|
|
||||||
* - Algorithm::MLD
|
* - Algorithm::MLD
|
||||||
* Multi Level Dijkstra, moderately fast in both pre-processing and query.
|
* Multi Level Dijkstra, moderately fast in both pre-processing and query.
|
||||||
*
|
*
|
||||||
@ -74,7 +70,6 @@ struct EngineConfig final
|
|||||||
enum class Algorithm
|
enum class Algorithm
|
||||||
{
|
{
|
||||||
CH,
|
CH,
|
||||||
CoreCH, // Deprecated, will be removed in v6.0
|
|
||||||
MLD
|
MLD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <boost/math/constants/constants.hpp>
|
#include <numbers>
|
||||||
|
|
||||||
namespace osrm::engine::map_matching
|
namespace osrm::engine::map_matching
|
||||||
{
|
{
|
||||||
@ -21,10 +21,8 @@ struct NormalDistribution
|
|||||||
// FIXME implement log-probability version since it's faster
|
// FIXME implement log-probability version since it's faster
|
||||||
double Density(const double val) const
|
double Density(const double val) const
|
||||||
{
|
{
|
||||||
using namespace boost::math::constants;
|
|
||||||
|
|
||||||
const double x = val - mean;
|
const double x = val - mean;
|
||||||
return 1.0 / (std::sqrt(two_pi<double>()) * standard_deviation) *
|
return 1.0 / (std::sqrt(2 * std::numbers::pi) * standard_deviation) *
|
||||||
std::exp(-x * x / (standard_deviation * standard_deviation));
|
std::exp(-x * x / (standard_deviation * standard_deviation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "util/integer_range.hpp"
|
#include "util/integer_range.hpp"
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/math/constants/constants.hpp>
|
#include <numbers>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
@ -14,7 +14,7 @@
|
|||||||
namespace osrm::engine::map_matching
|
namespace osrm::engine::map_matching
|
||||||
{
|
{
|
||||||
|
|
||||||
static const double log_2_pi = std::log(2. * boost::math::constants::pi<double>());
|
static const double log_2_pi = std::log(2. * std::numbers::pi);
|
||||||
static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits<double>::infinity();
|
static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits<double>::infinity();
|
||||||
static const double MINIMAL_LOG_PROB = std::numeric_limits<double>::lowest();
|
static const double MINIMAL_LOG_PROB = std::numeric_limits<double>::lowest();
|
||||||
static const std::size_t INVALID_STATE = std::numeric_limits<std::size_t>::max();
|
static const std::size_t INVALID_STATE = std::numeric_limits<std::size_t>::max();
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define ENGINE_MAP_MATCHING_CONFIDENCE_HPP
|
#define ENGINE_MAP_MATCHING_CONFIDENCE_HPP
|
||||||
|
|
||||||
#include "engine/map_matching/bayes_classifier.hpp"
|
#include "engine/map_matching/bayes_classifier.hpp"
|
||||||
|
#include <boost/assert.hpp>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace osrm::engine::map_matching
|
namespace osrm::engine::map_matching
|
||||||
|
@ -12,7 +12,6 @@ namespace osrm::engine
|
|||||||
|
|
||||||
// Algorithm-dependent heaps
|
// Algorithm-dependent heaps
|
||||||
// - CH algorithms use CH heaps
|
// - CH algorithms use CH heaps
|
||||||
// - CoreCH algorithms use CH
|
|
||||||
// - MLD algorithms use MLD heaps
|
// - MLD algorithms use MLD heaps
|
||||||
|
|
||||||
template <typename Algorithm> struct SearchEngineData
|
template <typename Algorithm> struct SearchEngineData
|
||||||
|
@ -296,24 +296,19 @@ inline engine_config_ptr argumentsToEngineConfig(const Napi::CallbackInfo &args)
|
|||||||
{
|
{
|
||||||
engine_config->algorithm = osrm::EngineConfig::Algorithm::CH;
|
engine_config->algorithm = osrm::EngineConfig::Algorithm::CH;
|
||||||
}
|
}
|
||||||
else if (algorithm_str == "CoreCH")
|
|
||||||
{
|
|
||||||
engine_config->algorithm = osrm::EngineConfig::Algorithm::CH;
|
|
||||||
}
|
|
||||||
else if (algorithm_str == "MLD")
|
else if (algorithm_str == "MLD")
|
||||||
{
|
{
|
||||||
engine_config->algorithm = osrm::EngineConfig::Algorithm::MLD;
|
engine_config->algorithm = osrm::EngineConfig::Algorithm::MLD;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThrowError(args.Env(), "algorithm option must be one of 'CH', 'CoreCH', or 'MLD'.");
|
ThrowError(args.Env(), "algorithm option must be one of 'CH', or 'MLD'.");
|
||||||
return engine_config_ptr();
|
return engine_config_ptr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!algorithm.IsUndefined())
|
else if (!algorithm.IsUndefined())
|
||||||
{
|
{
|
||||||
ThrowError(args.Env(),
|
ThrowError(args.Env(), "algorithm option must be a string and one of 'CH', or 'MLD'.");
|
||||||
"algorithm option must be a string and one of 'CH', 'CoreCH', or 'MLD'.");
|
|
||||||
return engine_config_ptr();
|
return engine_config_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <numbers>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ class CheapRuler
|
|||||||
static constexpr double FE = 1.0 / 298.257223563; // flattening
|
static constexpr double FE = 1.0 / 298.257223563; // flattening
|
||||||
|
|
||||||
static constexpr double E2 = FE * (2 - FE);
|
static constexpr double E2 = FE * (2 - FE);
|
||||||
static constexpr double RAD = M_PI / 180.0;
|
static constexpr double RAD = std::numbers::pi / 180.0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CheapRuler(double latitude)
|
explicit CheapRuler(double latitude)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
|
|
||||||
#include <boost/math/constants/constants.hpp>
|
#include <numbers>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -23,17 +23,9 @@ const constexpr double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
|
|||||||
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
|
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
|
||||||
const constexpr long double EARTH_RADIUS = 6372797.560856;
|
const constexpr long double EARTH_RADIUS = 6372797.560856;
|
||||||
|
|
||||||
inline double degToRad(const double degree)
|
inline double degToRad(const double degree) { return degree * (std::numbers::pi / 180.0); }
|
||||||
{
|
|
||||||
using namespace boost::math::constants;
|
|
||||||
return degree * (pi<double>() / 180.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double radToDeg(const double radian)
|
inline double radToDeg(const double radian) { return radian * (180.0 * std::numbers::inv_pi); }
|
||||||
{
|
|
||||||
using namespace boost::math::constants;
|
|
||||||
return radian * (180.0 * (1. / pi<double>()));
|
|
||||||
}
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
const constexpr static double METERS_PER_DEGREE_LAT = 110567.0;
|
const constexpr static double METERS_PER_DEGREE_LAT = 110567.0;
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
|
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
@ -126,8 +124,7 @@ inline bool requiresNameAnnounced(const StringView &from_name,
|
|||||||
|
|
||||||
// check similarity of names
|
// check similarity of names
|
||||||
const auto names_are_empty = from_name.empty() && to_name.empty();
|
const auto names_are_empty = from_name.empty() && to_name.empty();
|
||||||
const auto name_is_contained =
|
const auto name_is_contained = from_name.starts_with(to_name) || to_name.starts_with(from_name);
|
||||||
boost::starts_with(from_name, to_name) || boost::starts_with(to_name, from_name);
|
|
||||||
|
|
||||||
const auto checkForPrefixOrSuffixChange = [](const std::string_view first,
|
const auto checkForPrefixOrSuffixChange = [](const std::string_view first,
|
||||||
const std::string_view second,
|
const std::string_view second,
|
||||||
|
@ -156,7 +156,20 @@ template <typename NodeID,
|
|||||||
class QueryHeap
|
class QueryHeap
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
using HeapData = std::pair<Weight, Key>;
|
struct HeapData
|
||||||
|
{
|
||||||
|
Weight weight;
|
||||||
|
Key index;
|
||||||
|
|
||||||
|
bool operator>(const HeapData &other) const
|
||||||
|
{
|
||||||
|
if (weight == other.weight)
|
||||||
|
{
|
||||||
|
return index > other.index;
|
||||||
|
}
|
||||||
|
return weight > other.weight;
|
||||||
|
}
|
||||||
|
};
|
||||||
using HeapContainer = boost::heap::d_ary_heap<HeapData,
|
using HeapContainer = boost::heap::d_ary_heap<HeapData,
|
||||||
boost::heap::arity<4>,
|
boost::heap::arity<4>,
|
||||||
boost::heap::mutable_<true>,
|
boost::heap::mutable_<true>,
|
||||||
@ -195,7 +208,7 @@ class QueryHeap
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(node < std::numeric_limits<NodeID>::max());
|
BOOST_ASSERT(node < std::numeric_limits<NodeID>::max());
|
||||||
const auto index = static_cast<Key>(inserted_nodes.size());
|
const auto index = static_cast<Key>(inserted_nodes.size());
|
||||||
const auto handle = heap.push(std::make_pair(weight, index));
|
const auto handle = heap.emplace(HeapData{weight, index});
|
||||||
inserted_nodes.emplace_back(HeapNode{handle, node, weight, data});
|
inserted_nodes.emplace_back(HeapNode{handle, node, weight, data});
|
||||||
node_index[node] = index;
|
node_index[node] = index;
|
||||||
}
|
}
|
||||||
@ -278,19 +291,19 @@ class QueryHeap
|
|||||||
NodeID Min() const
|
NodeID Min() const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!heap.empty());
|
BOOST_ASSERT(!heap.empty());
|
||||||
return inserted_nodes[heap.top().second].node;
|
return inserted_nodes[heap.top().index].node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Weight MinKey() const
|
Weight MinKey() const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!heap.empty());
|
BOOST_ASSERT(!heap.empty());
|
||||||
return heap.top().first;
|
return heap.top().weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeID DeleteMin()
|
NodeID DeleteMin()
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!heap.empty());
|
BOOST_ASSERT(!heap.empty());
|
||||||
const Key removedIndex = heap.top().second;
|
const Key removedIndex = heap.top().index;
|
||||||
heap.pop();
|
heap.pop();
|
||||||
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
|
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
|
||||||
return inserted_nodes[removedIndex].node;
|
return inserted_nodes[removedIndex].node;
|
||||||
@ -299,7 +312,7 @@ class QueryHeap
|
|||||||
HeapNode &DeleteMinGetHeapNode()
|
HeapNode &DeleteMinGetHeapNode()
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!heap.empty());
|
BOOST_ASSERT(!heap.empty());
|
||||||
const Key removedIndex = heap.top().second;
|
const Key removedIndex = heap.top().index;
|
||||||
heap.pop();
|
heap.pop();
|
||||||
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
|
inserted_nodes[removedIndex].handle = heap.s_handle_from_iterator(heap.end());
|
||||||
return inserted_nodes[removedIndex];
|
return inserted_nodes[removedIndex];
|
||||||
@ -320,13 +333,13 @@ class QueryHeap
|
|||||||
const auto index = node_index.peek_index(node);
|
const auto index = node_index.peek_index(node);
|
||||||
auto &reference = inserted_nodes[index];
|
auto &reference = inserted_nodes[index];
|
||||||
reference.weight = weight;
|
reference.weight = weight;
|
||||||
heap.increase(reference.handle, std::make_pair(weight, index));
|
heap.increase(reference.handle, HeapData{weight, static_cast<Key>(index)});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecreaseKey(const HeapNode &heapNode)
|
void DecreaseKey(const HeapNode &heapNode)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!WasRemoved(heapNode.node));
|
BOOST_ASSERT(!WasRemoved(heapNode.node));
|
||||||
heap.increase(heapNode.handle, std::make_pair(heapNode.weight, (*heapNode.handle).second));
|
heap.increase(heapNode.handle, HeapData{heapNode.weight, (*heapNode.handle).index});
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#ifndef STRING_UTIL_HPP
|
#ifndef STRING_UTIL_HPP
|
||||||
#define STRING_UTIL_HPP
|
#define STRING_UTIL_HPP
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <cstddef>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -10,26 +11,30 @@
|
|||||||
namespace osrm::util
|
namespace osrm::util
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
std::array<uint8_t, 256> result{};
|
||||||
|
for (auto i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
result[i] = 1;
|
||||||
|
}
|
||||||
|
for (auto i : {'"', '\\'})
|
||||||
|
{
|
||||||
|
result[i] = 1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}();
|
||||||
|
|
||||||
inline bool RequiresJSONStringEscaping(const std::string &string)
|
inline bool RequiresJSONStringEscaping(const std::string &string)
|
||||||
{
|
{
|
||||||
for (const char letter : string)
|
uint8_t needs = 0;
|
||||||
|
for (uint8_t c : string)
|
||||||
{
|
{
|
||||||
switch (letter)
|
needs |= json_quotable_character[c];
|
||||||
{
|
|
||||||
case '\\':
|
|
||||||
case '"':
|
|
||||||
case '/':
|
|
||||||
case '\b':
|
|
||||||
case '\f':
|
|
||||||
case '\n':
|
|
||||||
case '\r':
|
|
||||||
case '\t':
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
return needs;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void EscapeJSONString(const std::string &input, std::string &output)
|
inline void EscapeJSONString(const std::string &input, std::string &output)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#include <boost/math/constants/constants.hpp>
|
#include <numbers>
|
||||||
|
|
||||||
namespace osrm::util
|
namespace osrm::util
|
||||||
{
|
{
|
||||||
@ -356,25 +356,21 @@ constexpr unsigned short atan_table[4096] = {
|
|||||||
0xffe0, 0xffea, 0xfff4, 0xffff};
|
0xffe0, 0xffea, 0xfff4, 0xffff};
|
||||||
|
|
||||||
// max value is pi/4
|
// max value is pi/4
|
||||||
#ifdef _MSC_VER // TODO: remove as soon as boost allows C++14 features with Visual Studio
|
const constexpr double SCALING_FACTOR = 4. * std::numbers::inv_pi * 0xFFFF;
|
||||||
const constexpr double SCALING_FACTOR = 4. / M_PI * 0xFFFF;
|
|
||||||
#else
|
|
||||||
const constexpr double SCALING_FACTOR = 4. / boost::math::constants::pi<double>() * 0xFFFF;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline double atan2_lookup(double y, double x)
|
inline double atan2_lookup(double y, double x)
|
||||||
{
|
{
|
||||||
using namespace boost::math::constants;
|
static constexpr auto half_pi = std::numbers::pi * 0.5;
|
||||||
|
|
||||||
if (std::abs(x) < std::numeric_limits<double>::epsilon())
|
if (std::abs(x) < std::numeric_limits<double>::epsilon())
|
||||||
{
|
{
|
||||||
if (y >= 0.)
|
if (y >= 0.)
|
||||||
{
|
{
|
||||||
return half_pi<double>();
|
return half_pi;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return -half_pi<double>();
|
return -half_pi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,25 +401,25 @@ inline double atan2_lookup(double y, double x)
|
|||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
angle = pi<double>() - angle;
|
angle = std::numbers::pi - angle;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
angle = -angle;
|
angle = -angle;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
angle = -pi<double>() + angle;
|
angle = -std::numbers::pi + angle;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
angle = half_pi<double>() - angle;
|
angle = half_pi - angle;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
angle = half_pi<double>() + angle;
|
angle = half_pi + angle;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
angle = -half_pi<double>() + angle;
|
angle = -half_pi + angle;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
angle = -half_pi<double>() - angle;
|
angle = -half_pi - angle;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return angle;
|
return angle;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
|
|
||||||
#include <boost/math/constants/constants.hpp>
|
#include <numbers>
|
||||||
|
|
||||||
namespace osrm::util::web_mercator
|
namespace osrm::util::web_mercator
|
||||||
{
|
{
|
||||||
@ -14,7 +14,7 @@ const constexpr double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
|
|||||||
// radius used by WGS84
|
// radius used by WGS84
|
||||||
const constexpr double EARTH_RADIUS_WGS84 = 6378137.0;
|
const constexpr double EARTH_RADIUS_WGS84 = 6378137.0;
|
||||||
// earth circumference devided by 2
|
// earth circumference devided by 2
|
||||||
const constexpr double MAXEXTENT = EARTH_RADIUS_WGS84 * boost::math::constants::pi<double>();
|
const constexpr double MAXEXTENT = EARTH_RADIUS_WGS84 * std::numbers::pi;
|
||||||
// ^ math functions are not constexpr since they have side-effects (setting errno) :(
|
// ^ math functions are not constexpr since they have side-effects (setting errno) :(
|
||||||
const constexpr double EPSG3857_MAX_LATITUDE = 85.051128779806592378; // 90(4*atan(exp(pi))/pi-1)
|
const constexpr double EPSG3857_MAX_LATITUDE = 85.051128779806592378; // 90(4*atan(exp(pi))/pi-1)
|
||||||
const constexpr double MAX_LONGITUDE = 180.0;
|
const constexpr double MAX_LONGITUDE = 180.0;
|
||||||
@ -103,8 +103,8 @@ inline void pixelToDegree(const double shift, double &x, double &y)
|
|||||||
const double b = shift / 2.0;
|
const double b = shift / 2.0;
|
||||||
x = (x - b) / shift * 360.0;
|
x = (x - b) / shift * 360.0;
|
||||||
// FIXME needs to be simplified
|
// FIXME needs to be simplified
|
||||||
const double g = (y - b) / -(shift / (2 * M_PI)) / detail::DEGREE_TO_RAD;
|
const double g = (y - b) / -(shift * 0.5 * std::numbers::inv_pi) / detail::DEGREE_TO_RAD;
|
||||||
static_assert(detail::DEGREE_TO_RAD / (2 * M_PI) - 1 / 360. < 0.0001, "");
|
static_assert(detail::DEGREE_TO_RAD * 0.5 * std::numbers::inv_pi - 1 / 360. < 0.0001, "");
|
||||||
y = static_cast<double>(yToLat(g));
|
y = static_cast<double>(yToLat(g));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
91
scripts/ci/download_gps_traces.py
Normal file
91
scripts/ci/download_gps_traces.py
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import requests
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import csv
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
def get_osm_gps_traces(min_lon, min_lat, max_lon, max_lat):
|
||||||
|
url = 'https://api.openstreetmap.org/api/0.6/trackpoints'
|
||||||
|
traces = []
|
||||||
|
|
||||||
|
lon_step = 0.25
|
||||||
|
lat_step = 0.25
|
||||||
|
|
||||||
|
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 = f'{current_min_lon},{current_min_lat},{current_max_lon},{current_max_lat}'
|
||||||
|
print(f"Requesting bbox: {bbox}", file=sys.stderr)
|
||||||
|
|
||||||
|
params = {
|
||||||
|
'bbox': bbox,
|
||||||
|
'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}: {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 a given bounding box.')
|
||||||
|
parser.add_argument('min_lon', type=float, help='Minimum longitude of the bounding box')
|
||||||
|
parser.add_argument('min_lat', type=float, help='Minimum latitude of the bounding box')
|
||||||
|
parser.add_argument('max_lon', type=float, help='Maximum longitude of the bounding box')
|
||||||
|
parser.add_argument('max_lat', type=float, help='Maximum latitude of the bounding box')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
gpx_data_traces = get_osm_gps_traces(args.min_lon, args.min_lat, args.max_lon, args.max_lat)
|
||||||
|
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)
|
74
scripts/ci/locustfile.py
Normal file
74
scripts/ci/locustfile.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
from locust import HttpUser, TaskSet, task, between
|
||||||
|
import csv
|
||||||
|
import random
|
||||||
|
from collections import defaultdict
|
||||||
|
import os
|
||||||
|
|
||||||
|
class OSRMTasks(TaskSet):
|
||||||
|
def on_start(self):
|
||||||
|
random.seed(42)
|
||||||
|
|
||||||
|
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())
|
||||||
|
|
||||||
|
@task
|
||||||
|
def get_route(self):
|
||||||
|
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}"
|
||||||
|
|
||||||
|
self.client.get(f"/route/v1/driving/{start_coord};{end_coord}?overview=full&steps=true", name="route")
|
||||||
|
|
||||||
|
@task
|
||||||
|
def get_table(self):
|
||||||
|
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])
|
||||||
|
|
||||||
|
self.client.get(f"/table/v1/driving/{coords_str}", name="table")
|
||||||
|
|
||||||
|
@task
|
||||||
|
def get_match(self):
|
||||||
|
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))])
|
||||||
|
|
||||||
|
with self.client.get(f"/match/v1/driving/{coords_str}?steps=true&radiuses={radiues_str}", name="match", catch_response=True) as response:
|
||||||
|
if response.status_code == 400:
|
||||||
|
j = response.json()
|
||||||
|
# it is expected that some of requests will fail with such error: map matching fails sometimes
|
||||||
|
if j['code'] == 'NoSegment' or j['code'] == 'NoMatch':
|
||||||
|
response.success()
|
||||||
|
|
||||||
|
@task
|
||||||
|
def get_nearest(self):
|
||||||
|
coord = random.choice(self.coordinates)
|
||||||
|
coord_str = f"{coord[1]:.6f},{coord[0]:.6f}"
|
||||||
|
|
||||||
|
self.client.get(f"/nearest/v1/driving/{coord_str}", name="nearest")
|
||||||
|
|
||||||
|
@task
|
||||||
|
def get_trip(self):
|
||||||
|
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])
|
||||||
|
|
||||||
|
self.client.get(f"/trip/v1/driving/{coords_str}?steps=true", name="trip")
|
||||||
|
|
||||||
|
class OSRMUser(HttpUser):
|
||||||
|
tasks = [OSRMTasks]
|
||||||
|
# random wait time between requests to not load server for 100%
|
||||||
|
wait_time = between(0.05, 0.5)
|
@ -16,8 +16,10 @@ def create_markdown_table(results):
|
|||||||
rows = []
|
rows = []
|
||||||
for result in results:
|
for result in results:
|
||||||
name = result['name']
|
name = result['name']
|
||||||
base = result['base'].replace('\n', '<br/>')
|
base = result['base'] or ''
|
||||||
pr = result['pr'].replace('\n', '<br/>')
|
base = base.replace('\n', '<br/>')
|
||||||
|
pr = result['pr'] or ''
|
||||||
|
pr = pr.replace('\n', '<br/>')
|
||||||
row = f"| {name} | {base} | {pr} |"
|
row = f"| {name} | {base} | {pr} |"
|
||||||
rows.append(row)
|
rows.append(row)
|
||||||
return f"{header}\n" + "\n".join(rows)
|
return f"{header}\n" + "\n".join(rows)
|
||||||
@ -75,7 +77,14 @@ def main():
|
|||||||
pr_body = pr_details.get('body', '') or ''
|
pr_body = pr_details.get('body', '') or ''
|
||||||
|
|
||||||
markdown_table = create_markdown_table(benchmark_results)
|
markdown_table = create_markdown_table(benchmark_results)
|
||||||
new_benchmark_section = f"<!-- BENCHMARK_RESULTS_START -->\n## Benchmark Results\n{markdown_table}\n<!-- BENCHMARK_RESULTS_END -->"
|
new_benchmark_section = f"""
|
||||||
|
<!-- BENCHMARK_RESULTS_START -->
|
||||||
|
<details><summary><h2>Benchmark Results</h2></summary>
|
||||||
|
|
||||||
|
{markdown_table}
|
||||||
|
</details>
|
||||||
|
<!-- BENCHMARK_RESULTS_END -->
|
||||||
|
"""
|
||||||
|
|
||||||
if re.search(r'<!-- BENCHMARK_RESULTS_START -->.*<!-- BENCHMARK_RESULTS_END -->', pr_body, re.DOTALL):
|
if re.search(r'<!-- BENCHMARK_RESULTS_START -->.*<!-- BENCHMARK_RESULTS_END -->', pr_body, re.DOTALL):
|
||||||
updated_body = re.sub(
|
updated_body = re.sub(
|
||||||
|
31
scripts/ci/process_locust_benchmark_results.py
Normal file
31
scripts/ci/process_locust_benchmark_results.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import sys
|
||||||
|
import csv
|
||||||
|
|
||||||
|
def main(locust_csv_base_name, suffix, output_folder):
|
||||||
|
with open(f"{locust_csv_base_name}_stats.csv", 'r') as file:
|
||||||
|
reader = csv.DictReader(file)
|
||||||
|
for row in reader:
|
||||||
|
name = row['Name']
|
||||||
|
if name == 'Aggregated': continue
|
||||||
|
|
||||||
|
statistics = f'''
|
||||||
|
requests: {row['Request Count']}
|
||||||
|
failures: {row['Failure Count']}
|
||||||
|
req/s: {float(row['Requests/s']):.3f}req/s
|
||||||
|
avg: {float(row['Average Response Time']):.3f}ms
|
||||||
|
50%: {row['50%']}ms
|
||||||
|
75%: {row['75%']}ms
|
||||||
|
95%: {row['95%']}ms
|
||||||
|
98%: {row['98%']}ms
|
||||||
|
99%: {row['99%']}ms
|
||||||
|
min: {float(row['Min Response Time']):.3f}ms
|
||||||
|
max: {float(row['Max Response Time']):.3f}ms
|
||||||
|
'''
|
||||||
|
with open(f"{output_folder}/e2e_{name}_{suffix}.bench", 'w') as f:
|
||||||
|
f.write(statistics)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
if len(sys.argv) != 4:
|
||||||
|
print(f"Usage: {sys.argv[0]} <locust csv base name> <suffix> <output folder>")
|
||||||
|
sys.exit(1)
|
||||||
|
main(sys.argv[1], sys.argv[2], sys.argv[3])
|
@ -13,12 +13,45 @@ function run_benchmarks_for_folder {
|
|||||||
|
|
||||||
./$BENCHMARKS_FOLDER/match-bench "./$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/match_mld.bench"
|
./$BENCHMARKS_FOLDER/match-bench "./$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/match_mld.bench"
|
||||||
./$BENCHMARKS_FOLDER/match-bench "./$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/match_ch.bench"
|
./$BENCHMARKS_FOLDER/match-bench "./$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/match_ch.bench"
|
||||||
./$BENCHMARKS_FOLDER/route-bench "./$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/route_mld.bench" || true # TODO: remove `true` when this benchmark will be merged to master
|
./$BENCHMARKS_FOLDER/route-bench "./$FOLDER/test/data/mld/monaco.osrm" mld > "$RESULTS_FOLDER/route_mld.bench"
|
||||||
./$BENCHMARKS_FOLDER/route-bench "./$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/route_ch.bench" || true # TODO: remove `true` when this benchmark will be merged to master
|
./$BENCHMARKS_FOLDER/route-bench "./$FOLDER/test/data/ch/monaco.osrm" ch > "$RESULTS_FOLDER/route_ch.bench"
|
||||||
./$BENCHMARKS_FOLDER/alias-bench > "$RESULTS_FOLDER/alias.bench"
|
./$BENCHMARKS_FOLDER/alias-bench > "$RESULTS_FOLDER/alias.bench"
|
||||||
./$BENCHMARKS_FOLDER/json-render-bench "./$FOLDER/src/benchmarks/portugal_to_korea.json" > "$RESULTS_FOLDER/json-render.bench"
|
./$BENCHMARKS_FOLDER/json-render-bench "./$FOLDER/src/benchmarks/portugal_to_korea.json" > "$RESULTS_FOLDER/json-render.bench"
|
||||||
./$BENCHMARKS_FOLDER/packedvector-bench > "$RESULTS_FOLDER/packedvector.bench"
|
./$BENCHMARKS_FOLDER/packedvector-bench > "$RESULTS_FOLDER/packedvector.bench"
|
||||||
./$BENCHMARKS_FOLDER/rtree-bench "./$FOLDER/test/data/monaco.osrm.ramIndex" "./$FOLDER/test/data/monaco.osrm.fileIndex" "./$FOLDER/test/data/monaco.osrm.nbg_nodes" > "$RESULTS_FOLDER/rtree.bench"
|
./$BENCHMARKS_FOLDER/rtree-bench "./$FOLDER/test/data/monaco.osrm.ramIndex" "./$FOLDER/test/data/monaco.osrm.fileIndex" "./$FOLDER/test/data/monaco.osrm.nbg_nodes" > "$RESULTS_FOLDER/rtree.bench"
|
||||||
|
|
||||||
|
BINARIES_FOLDER="$FOLDER/build"
|
||||||
|
|
||||||
|
cp ~/data.osm.pbf $FOLDER
|
||||||
|
$BINARIES_FOLDER/osrm-extract -p $FOLDER/profiles/car.lua $FOLDER/data.osm.pbf
|
||||||
|
$BINARIES_FOLDER/osrm-partition $FOLDER/data.osrm
|
||||||
|
$BINARIES_FOLDER/osrm-customize $FOLDER/data.osrm
|
||||||
|
$BINARIES_FOLDER/osrm-contract $FOLDER/data.osrm
|
||||||
|
|
||||||
|
if [ -f "$FOLDER/scripts/ci/locustfile.py" ]; then
|
||||||
|
for ALGORITHM in mld ch; do
|
||||||
|
$BINARIES_FOLDER/osrm-routed --algorithm $ALGORITHM $FOLDER/data.osrm &
|
||||||
|
OSRM_ROUTED_PID=$!
|
||||||
|
|
||||||
|
# wait for osrm-routed to start
|
||||||
|
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"
|
||||||
|
locust -f $FOLDER/scripts/ci/locustfile.py \
|
||||||
|
--headless \
|
||||||
|
--processes -1 \
|
||||||
|
--users 10 \
|
||||||
|
--spawn-rate 1 \
|
||||||
|
--host http://localhost:5000 \
|
||||||
|
--run-time 1m \
|
||||||
|
--csv=locust_results_$ALGORITHM \
|
||||||
|
--loglevel ERROR
|
||||||
|
|
||||||
|
python3 $FOLDER/scripts/ci/process_locust_benchmark_results.py locust_results_$ALGORITHM $ALGORITHM $RESULTS_FOLDER
|
||||||
|
|
||||||
|
|
||||||
|
kill -0 $OSRM_ROUTED_PID
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
run_benchmarks_for_folder $1 "${1}_results"
|
run_benchmarks_for_folder $1 "${1}_results"
|
||||||
|
@ -58,7 +58,6 @@ IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
|||||||
|
|
||||||
SET test_region=monaco
|
SET test_region=monaco
|
||||||
SET test_region_ch=ch\monaco
|
SET test_region_ch=ch\monaco
|
||||||
SET test_region_corech=corech\monaco
|
|
||||||
SET test_region_mld=mld\monaco
|
SET test_region_mld=mld\monaco
|
||||||
SET test_osm=%test_region%.osm.pbf
|
SET test_osm=%test_region%.osm.pbf
|
||||||
COPY %PROJECT_DIR%\test\data\%test_region%.osm.pbf %test_osm%
|
COPY %PROJECT_DIR%\test\data\%test_region%.osm.pbf %test_osm%
|
||||||
@ -68,18 +67,13 @@ IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
|||||||
MKDIR ch
|
MKDIR ch
|
||||||
XCOPY %test_region%.osrm.* ch\
|
XCOPY %test_region%.osrm.* 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
|
MKDIR mld
|
||||||
XCOPY %test_region%.osrm.* mld\
|
XCOPY %test_region%.osrm.* mld\
|
||||||
XCOPY %test_region%.osrm mld\
|
XCOPY %test_region%.osrm mld\
|
||||||
%CONFIGURATION%\osrm-contract.exe %test_region_ch%.osrm
|
%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-partition.exe %test_region_mld%.osrm
|
||||||
%CONFIGURATION%\osrm-customize.exe %test_region_mld%.osrm
|
%CONFIGURATION%\osrm-customize.exe %test_region_mld%.osrm
|
||||||
XCOPY /Y ch\*.* ..\test\data\ch\
|
XCOPY /Y ch\*.* ..\test\data\ch\
|
||||||
XCOPY /Y corech\*.* ..\test\data\corech\
|
|
||||||
XCOPY /Y mld\*.* ..\test\data\mld\
|
XCOPY /Y mld\*.* ..\test\data\mld\
|
||||||
unit_tests\%CONFIGURATION%\library-tests.exe
|
unit_tests\%CONFIGURATION%\library-tests.exe
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "util/coordinate_calculation.hpp"
|
#include "util/coordinate_calculation.hpp"
|
||||||
|
|
||||||
#include <boost/optional/optional_io.hpp>
|
#include <boost/optional/optional_io.hpp>
|
||||||
|
#include <numbers>
|
||||||
|
|
||||||
namespace osrm::extractor::intersection
|
namespace osrm::extractor::intersection
|
||||||
{
|
{
|
||||||
@ -79,11 +80,11 @@ namespace
|
|||||||
{
|
{
|
||||||
double findAngleBisector(double alpha, double beta)
|
double findAngleBisector(double alpha, double beta)
|
||||||
{
|
{
|
||||||
alpha *= M_PI / 180.;
|
alpha *= std::numbers::pi / 180.;
|
||||||
beta *= M_PI / 180.;
|
beta *= std::numbers::pi / 180.;
|
||||||
const auto average =
|
const auto average =
|
||||||
180. * std::atan2(std::sin(alpha) + std::sin(beta), std::cos(alpha) + std::cos(beta)) /
|
180. * std::atan2(std::sin(alpha) + std::sin(beta), std::cos(alpha) + std::cos(beta)) *
|
||||||
M_PI;
|
std::numbers::inv_pi;
|
||||||
return std::fmod(average + 360., 360.);
|
return std::fmod(average + 360., 360.);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ bool MergableRoadDetector::IsCircularShape(const NodeID intersection_node,
|
|||||||
// ---- ----
|
// ---- ----
|
||||||
// \ /
|
// \ /
|
||||||
// -------
|
// -------
|
||||||
const auto constexpr CIRCULAR_POLYGON_ISOPERIMETRIC_LOWER_BOUND = 0.85 / (4 * M_PI);
|
const auto constexpr CIRCULAR_POLYGON_ISOPERIMETRIC_LOWER_BOUND = 0.85 / (4 * std::numbers::pi);
|
||||||
if (connect_again && coordinates_to_the_left.front() == coordinates_to_the_left.back())
|
if (connect_again && coordinates_to_the_left.front() == coordinates_to_the_left.back())
|
||||||
{ // if the left and right roads connect again and are closed polygons ...
|
{ // if the left and right roads connect again and are closed polygons ...
|
||||||
const auto area = util::coordinate_calculation::computeArea(coordinates_to_the_left);
|
const auto area = util::coordinate_calculation::computeArea(coordinates_to_the_left);
|
||||||
@ -359,7 +359,7 @@ bool MergableRoadDetector::IsCircularShape(const NodeID intersection_node,
|
|||||||
const auto area_to_squared_perimeter_ratio = std::abs(area) / (perimeter * perimeter);
|
const auto area_to_squared_perimeter_ratio = std::abs(area) / (perimeter * perimeter);
|
||||||
|
|
||||||
// then don't merge roads if A/L² is greater than the lower bound
|
// then don't merge roads if A/L² is greater than the lower bound
|
||||||
BOOST_ASSERT(area_to_squared_perimeter_ratio <= 1. / (4 * M_PI));
|
BOOST_ASSERT(area_to_squared_perimeter_ratio <= 1. / (4 * std::numbers::pi));
|
||||||
if (area_to_squared_perimeter_ratio >= CIRCULAR_POLYGON_ISOPERIMETRIC_LOWER_BOUND)
|
if (area_to_squared_perimeter_ratio >= CIRCULAR_POLYGON_ISOPERIMETRIC_LOWER_BOUND)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -337,7 +337,7 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
|||||||
return RoundaboutType::RoundaboutIntersection;
|
return RoundaboutType::RoundaboutIntersection;
|
||||||
}
|
}
|
||||||
|
|
||||||
const double radius = roundabout_length / (2 * M_PI);
|
const double radius = roundabout_length * 0.5 * std::numbers::inv_pi;
|
||||||
|
|
||||||
// Looks like a rotary: large roundabout with dedicated name
|
// Looks like a rotary: large roundabout with dedicated name
|
||||||
// do we have a dedicated name for the rotary, if not its a roundabout
|
// do we have a dedicated name for the rotary, if not its a roundabout
|
||||||
|
@ -64,7 +64,7 @@ Napi::Object Engine::Init(Napi::Env env, Napi::Object exports)
|
|||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param {Object|String} [options={shared_memory: true}] Options for creating an OSRM object or string to the `.osrm` file.
|
* @param {Object|String} [options={shared_memory: true}] Options for creating an OSRM object or string to the `.osrm` file.
|
||||||
* @param {String} [options.algorithm] The algorithm to use for routing. Can be 'CH', 'CoreCH' or 'MLD'. Default is 'CH'.
|
* @param {String} [options.algorithm] The algorithm to use for routing. Can be 'CH', or 'MLD'. Default is 'CH'.
|
||||||
* Make sure you prepared the dataset with the correct toolchain.
|
* Make sure you prepared the dataset with the correct toolchain.
|
||||||
* @param {Boolean} [options.shared_memory] Connects to the persistent shared memory datastore.
|
* @param {Boolean} [options.shared_memory] Connects to the persistent shared memory datastore.
|
||||||
* This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
|
* This requires you to run `osrm-datastore` prior to creating an `OSRM` object.
|
||||||
|
@ -36,13 +36,6 @@ OSRM::OSRM(engine::EngineConfig &config)
|
|||||||
|
|
||||||
// Now, check that the algorithm requested can be used with the data
|
// Now, check that the algorithm requested can be used with the data
|
||||||
// that's available.
|
// that's available.
|
||||||
|
|
||||||
if (config.algorithm == EngineConfig::Algorithm::CoreCH)
|
|
||||||
{
|
|
||||||
util::Log(logWARNING) << "Using CoreCH is deprecated. Falling back to CH";
|
|
||||||
config.algorithm = EngineConfig::Algorithm::CH;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (config.algorithm)
|
switch (config.algorithm)
|
||||||
{
|
{
|
||||||
case EngineConfig::Algorithm::CH:
|
case EngineConfig::Algorithm::CH:
|
||||||
|
@ -61,7 +61,7 @@ std::istream &operator>>(std::istream &in, EngineConfig::Algorithm &algorithm)
|
|||||||
in >> token;
|
in >> token;
|
||||||
boost::to_lower(token);
|
boost::to_lower(token);
|
||||||
|
|
||||||
if (token == "ch" || token == "corech")
|
if (token == "ch")
|
||||||
algorithm = EngineConfig::Algorithm::CH;
|
algorithm = EngineConfig::Algorithm::CH;
|
||||||
else if (token == "mld")
|
else if (token == "mld")
|
||||||
algorithm = EngineConfig::Algorithm::MLD;
|
algorithm = EngineConfig::Algorithm::MLD;
|
||||||
@ -159,7 +159,7 @@ inline unsigned generateServerProgramOptions(const int argc,
|
|||||||
("algorithm,a",
|
("algorithm,a",
|
||||||
value<EngineConfig::Algorithm>(&config.algorithm)
|
value<EngineConfig::Algorithm>(&config.algorithm)
|
||||||
->default_value(EngineConfig::Algorithm::CH, "CH"),
|
->default_value(EngineConfig::Algorithm::CH, "CH"),
|
||||||
"Algorithm to use for the data. Can be CH, CoreCH, MLD.") //
|
"Algorithm to use for the data. Can be CH, MLD.") //
|
||||||
("disable-feature-dataset",
|
("disable-feature-dataset",
|
||||||
value<std::vector<storage::FeatureDataset>>(&config.disable_feature_dataset)->multitoken(),
|
value<std::vector<storage::FeatureDataset>>(&config.disable_feature_dataset)->multitoken(),
|
||||||
"Disables a feature dataset from being loaded into memory if not needed. Options: "
|
"Disables a feature dataset from being loaded into memory if not needed. Options: "
|
||||||
|
@ -146,7 +146,6 @@ double bearing(const Coordinate coordinate_1, const Coordinate coordinate_2)
|
|||||||
|
|
||||||
double computeAngle(const Coordinate first, const Coordinate second, const Coordinate third)
|
double computeAngle(const Coordinate first, const Coordinate second, const Coordinate third)
|
||||||
{
|
{
|
||||||
using namespace boost::math::constants;
|
|
||||||
using namespace coordinate_calculation;
|
using namespace coordinate_calculation;
|
||||||
|
|
||||||
if (first == second || second == third)
|
if (first == second || second == third)
|
||||||
@ -163,7 +162,7 @@ double computeAngle(const Coordinate first, const Coordinate second, const Coord
|
|||||||
const double v2y =
|
const double v2y =
|
||||||
web_mercator::latToY(toFloating(third.lat)) - web_mercator::latToY(toFloating(second.lat));
|
web_mercator::latToY(toFloating(third.lat)) - web_mercator::latToY(toFloating(second.lat));
|
||||||
|
|
||||||
double angle = (atan2_lookup(v2y, v2x) - atan2_lookup(v1y, v1x)) * 180. / pi<double>();
|
double angle = (atan2_lookup(v2y, v2x) - atan2_lookup(v1y, v1x)) * 180. * std::numbers::inv_pi;
|
||||||
|
|
||||||
while (angle < 0.)
|
while (angle < 0.)
|
||||||
{
|
{
|
||||||
|
@ -14,20 +14,16 @@ PROFILE:=$(PROFILE_ROOT)/car.lua
|
|||||||
|
|
||||||
all: data
|
all: data
|
||||||
|
|
||||||
data: ch/$(DATA_NAME).osrm.hsgr corech/$(DATA_NAME).osrm.hsgr mld/$(DATA_NAME).osrm.partition
|
data: ch/$(DATA_NAME).osrm.hsgr mld/$(DATA_NAME).osrm.partition
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -r $(DATA_NAME).*
|
-rm -r $(DATA_NAME).*
|
||||||
-rm -r ch corech mld
|
-rm -r ch mld
|
||||||
|
|
||||||
ch/$(DATA_NAME).osrm: $(DATA_NAME).osrm
|
ch/$(DATA_NAME).osrm: $(DATA_NAME).osrm
|
||||||
mkdir -p ch
|
mkdir -p ch
|
||||||
cp $(DATA_NAME).osrm.* ch/
|
cp $(DATA_NAME).osrm.* ch/
|
||||||
|
|
||||||
corech/$(DATA_NAME).osrm: $(DATA_NAME).osrm
|
|
||||||
mkdir -p corech
|
|
||||||
cp $(DATA_NAME).osrm.* corech/
|
|
||||||
|
|
||||||
mld/$(DATA_NAME).osrm: $(DATA_NAME).osrm
|
mld/$(DATA_NAME).osrm: $(DATA_NAME).osrm
|
||||||
mkdir -p mld
|
mkdir -p mld
|
||||||
cp $(DATA_NAME).osrm.* mld/
|
cp $(DATA_NAME).osrm.* mld/
|
||||||
@ -42,10 +38,6 @@ ch/$(DATA_NAME).osrm.hsgr: ch/$(DATA_NAME).osrm $(PROFILE) $(OSRM_CONTRACT)
|
|||||||
@echo "Running osrm-contract..."
|
@echo "Running osrm-contract..."
|
||||||
$(TIMER) "osrm-contract\t$@" $(OSRM_CONTRACT) $<
|
$(TIMER) "osrm-contract\t$@" $(OSRM_CONTRACT) $<
|
||||||
|
|
||||||
corech/$(DATA_NAME).osrm.hsgr: corech/$(DATA_NAME).osrm $(PROFILE) $(OSRM_CONTRACT)
|
|
||||||
@echo "Running osrm-contract..."
|
|
||||||
$(TIMER) "osrm-contract\t$@" $(OSRM_CONTRACT) --core=0.5 $<
|
|
||||||
|
|
||||||
mld/$(DATA_NAME).osrm.partition: mld/$(DATA_NAME).osrm $(PROFILE) $(OSRM_PARTITION)
|
mld/$(DATA_NAME).osrm.partition: mld/$(DATA_NAME).osrm $(PROFILE) $(OSRM_PARTITION)
|
||||||
@echo "Running osrm-partition..."
|
@echo "Running osrm-partition..."
|
||||||
$(TIMER) "osrm-partition\t$@" $(OSRM_PARTITION) $<
|
$(TIMER) "osrm-partition\t$@" $(OSRM_PARTITION) $<
|
||||||
@ -61,11 +53,6 @@ benchmark: data $(DATA_NAME).requests
|
|||||||
$(TIMER) "queries\tCH" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
|
$(TIMER) "queries\tCH" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
|
||||||
@cat osrm-routed.pid | xargs kill
|
@cat osrm-routed.pid | xargs kill
|
||||||
@rm osrm-routed.pid
|
@rm osrm-routed.pid
|
||||||
@/bin/sh -c '$(OSRM_ROUTED) --algorithm=CoreCH corech/$(DATA_NAME).osrm > /dev/null & echo "$$!" > osrm-routed.pid'
|
|
||||||
@sleep 1
|
|
||||||
$(TIMER) "queries\tCoreCH" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
|
|
||||||
@cat osrm-routed.pid | xargs kill
|
|
||||||
@rm osrm-routed.pid
|
|
||||||
@/bin/sh -c '$(OSRM_ROUTED) --algorithm=MLD mld/$(DATA_NAME).osrm > /dev/null & echo "$$!" > osrm-routed.pid'
|
@/bin/sh -c '$(OSRM_ROUTED) --algorithm=MLD mld/$(DATA_NAME).osrm > /dev/null & echo "$$!" > osrm-routed.pid'
|
||||||
@sleep 1
|
@sleep 1
|
||||||
$(TIMER) "queries\tMLD" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
|
$(TIMER) "queries\tMLD" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
|
||||||
|
BIN
test/data/berlin_gps_traces.csv.gz
Normal file
BIN
test/data/berlin_gps_traces.csv.gz
Normal file
Binary file not shown.
@ -16,12 +16,10 @@ exports.test_tile = {'at': [17059, 11948, 15], 'size': 159125};
|
|||||||
if (process.env.OSRM_DATA_PATH !== undefined) {
|
if (process.env.OSRM_DATA_PATH !== undefined) {
|
||||||
exports.data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "ch/monaco.osrm");
|
exports.data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "ch/monaco.osrm");
|
||||||
exports.mld_data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "mld/monaco.osrm");
|
exports.mld_data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "mld/monaco.osrm");
|
||||||
exports.corech_data_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "corech/monaco.osrm");
|
|
||||||
exports.test_memory_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "test_memory");
|
exports.test_memory_path = path.join(path.resolve(process.env.OSRM_DATA_PATH), "test_memory");
|
||||||
console.log('Setting custom data path to ' + exports.data_path);
|
console.log('Setting custom data path to ' + exports.data_path);
|
||||||
} else {
|
} else {
|
||||||
exports.data_path = path.resolve(path.join(__dirname, "../data/ch/monaco.osrm"));
|
exports.data_path = path.resolve(path.join(__dirname, "../data/ch/monaco.osrm"));
|
||||||
exports.mld_data_path = path.resolve(path.join(__dirname, "../data/mld/monaco.osrm"));
|
exports.mld_data_path = path.resolve(path.join(__dirname, "../data/mld/monaco.osrm"));
|
||||||
exports.corech_data_path = path.resolve(path.join(__dirname, "../data/corech/monaco.osrm"));
|
|
||||||
exports.test_memory_path = path.resolve(path.join(__dirname, "../data/test_memory"));
|
exports.test_memory_path = path.resolve(path.join(__dirname, "../data/test_memory"));
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ var test = require('tape');
|
|||||||
var monaco_path = require('./constants').data_path;
|
var monaco_path = require('./constants').data_path;
|
||||||
var test_memory_file = require('./constants').test_memory_file;
|
var test_memory_file = require('./constants').test_memory_file;
|
||||||
var monaco_mld_path = require('./constants').mld_data_path;
|
var monaco_mld_path = require('./constants').mld_data_path;
|
||||||
var monaco_corech_path = require('./constants').corech_data_path;
|
|
||||||
|
|
||||||
test('constructor: throws if new keyword is not used', function(assert) {
|
test('constructor: throws if new keyword is not used', function(assert) {
|
||||||
assert.plan(1);
|
assert.plan(1);
|
||||||
@ -65,13 +64,13 @@ test('constructor: throws if given a non-string/obj argument', function(assert)
|
|||||||
test('constructor: throws if given an unkown algorithm', function(assert) {
|
test('constructor: throws if given an unkown algorithm', function(assert) {
|
||||||
assert.plan(1);
|
assert.plan(1);
|
||||||
assert.throws(function() { new OSRM({algorithm: 'Foo', shared_memory: true}); },
|
assert.throws(function() { new OSRM({algorithm: 'Foo', shared_memory: true}); },
|
||||||
/algorithm option must be one of 'CH', 'CoreCH', or 'MLD'/);
|
/algorithm option must be one of 'CH', or 'MLD'/);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('constructor: throws if given an invalid algorithm', function(assert) {
|
test('constructor: throws if given an invalid algorithm', function(assert) {
|
||||||
assert.plan(1);
|
assert.plan(1);
|
||||||
assert.throws(function() { new OSRM({algorithm: 3, shared_memory: true}); },
|
assert.throws(function() { new OSRM({algorithm: 3, shared_memory: true}); },
|
||||||
/algorithm option must be a string and one of 'CH', 'CoreCH', or 'MLD'/);
|
/algorithm option must be a string and one of 'CH', or 'MLD'/);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('constructor: loads MLD if given as algorithm', function(assert) {
|
test('constructor: loads MLD if given as algorithm', function(assert) {
|
||||||
@ -86,22 +85,8 @@ test('constructor: loads CH if given as algorithm', function(assert) {
|
|||||||
assert.ok(osrm);
|
assert.ok(osrm);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('constructor: loads CoreCH if given as algorithm', function(assert) {
|
|
||||||
assert.plan(1);
|
|
||||||
var osrm = new OSRM({algorithm: 'CoreCH', path: monaco_corech_path});
|
|
||||||
assert.ok(osrm);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('constructor: autoswitches to CoreCH for a CH dataset if capable', function(assert) {
|
|
||||||
assert.plan(1);
|
|
||||||
var osrm = new OSRM({algorithm: 'CH', path: monaco_corech_path});
|
|
||||||
assert.ok(osrm);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('constructor: throws if data doesn\'t match algorithm', function(assert) {
|
test('constructor: throws if data doesn\'t match algorithm', function(assert) {
|
||||||
assert.plan(3);
|
assert.plan(1);
|
||||||
assert.throws(function() { new OSRM({algorithm: 'CoreCH', path: monaco_mld_path}); }, /Could not find any metrics for CH/, 'CoreCH with MLD data');
|
|
||||||
assert.ok(new OSRM({algorithm: 'CoreCH', path: monaco_path}), 'CoreCH with CH data');
|
|
||||||
assert.throws(function() { new OSRM({algorithm: 'MLD', path: monaco_path}); }, /Could not find any metrics for MLD/, 'MLD with CH data');
|
assert.throws(function() { new OSRM({algorithm: 'MLD', path: monaco_path}); }, /Could not find any metrics for MLD/, 'MLD with CH data');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ var OSRM = require('../../');
|
|||||||
var test = require('tape');
|
var test = require('tape');
|
||||||
var monaco_path = require('./constants').data_path;
|
var monaco_path = require('./constants').data_path;
|
||||||
var monaco_mld_path = require('./constants').mld_data_path;
|
var monaco_mld_path = require('./constants').mld_data_path;
|
||||||
var monaco_corech_path = require('./constants').corech_data_path;
|
|
||||||
var three_test_coordinates = require('./constants').three_test_coordinates;
|
var three_test_coordinates = require('./constants').three_test_coordinates;
|
||||||
var two_test_coordinates = require('./constants').two_test_coordinates;
|
var two_test_coordinates = require('./constants').two_test_coordinates;
|
||||||
const flatbuffers = require('../../features/support/flatbuffers').flatbuffers;
|
const flatbuffers = require('../../features/support/flatbuffers').flatbuffers;
|
||||||
@ -76,32 +75,6 @@ test('route: routes Monaco on MLD', function(assert) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('route: routes Monaco on CoreCH', function(assert) {
|
|
||||||
assert.plan(5);
|
|
||||||
var osrm = new OSRM({path: monaco_corech_path, algorithm: 'CoreCH'});
|
|
||||||
osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, function(err, route) {
|
|
||||||
assert.ifError(err);
|
|
||||||
assert.ok(route.waypoints);
|
|
||||||
assert.ok(route.routes);
|
|
||||||
assert.ok(route.routes.length);
|
|
||||||
assert.ok(route.routes[0].geometry);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('route: routes Monaco and returns a JSON buffer', function(assert) {
|
|
||||||
assert.plan(6);
|
|
||||||
var osrm = new OSRM({path: monaco_corech_path, algorithm: 'CoreCH'});
|
|
||||||
osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, { format: 'json_buffer'}, function(err, result) {
|
|
||||||
assert.ifError(err);
|
|
||||||
assert.ok(result instanceof Buffer);
|
|
||||||
const route = JSON.parse(result);
|
|
||||||
assert.ok(route.waypoints);
|
|
||||||
assert.ok(route.routes);
|
|
||||||
assert.ok(route.routes.length);
|
|
||||||
assert.ok(route.routes[0].geometry);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('route: throws with too few or invalid args', function(assert) {
|
test('route: throws with too few or invalid args', function(assert) {
|
||||||
assert.plan(4);
|
assert.plan(4);
|
||||||
var osrm = new OSRM(monaco_path);
|
var osrm = new OSRM(monaco_path);
|
||||||
|
@ -14,14 +14,6 @@ BOOST_AUTO_TEST_CASE(test_incompatible_with_mld)
|
|||||||
osrm::exception);
|
osrm::exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_compatible_with_corech_fallback)
|
|
||||||
{
|
|
||||||
// Note - this tests that given the CoreCH algorithm config option, configuration falls back to
|
|
||||||
// CH and is compatible with CH data
|
|
||||||
BOOST_CHECK_NO_THROW(
|
|
||||||
getOSRM(OSRM_TEST_DATA_DIR "/ch/monaco.osrm", osrm::EngineConfig::Algorithm::CoreCH));
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_incompatible_with_ch)
|
BOOST_AUTO_TEST_CASE(test_incompatible_with_ch)
|
||||||
{
|
{
|
||||||
// Can't use the CH algorithm with MLD data
|
// Can't use the CH algorithm with MLD data
|
||||||
|
@ -18,16 +18,6 @@ BOOST_AUTO_TEST_CASE(test_ch)
|
|||||||
OSRM osrm{config};
|
OSRM osrm{config};
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_corech)
|
|
||||||
{
|
|
||||||
using namespace osrm;
|
|
||||||
EngineConfig config;
|
|
||||||
config.use_shared_memory = false;
|
|
||||||
config.storage_config = storage::StorageConfig(OSRM_TEST_DATA_DIR "/corech/monaco.osrm");
|
|
||||||
config.algorithm = EngineConfig::Algorithm::CoreCH;
|
|
||||||
OSRM osrm{config};
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_mld)
|
BOOST_AUTO_TEST_CASE(test_mld)
|
||||||
{
|
{
|
||||||
using namespace osrm;
|
using namespace osrm;
|
||||||
|
@ -198,18 +198,6 @@ void test_tile_ch(bool use_string_only_api)
|
|||||||
BOOST_AUTO_TEST_CASE(test_tile_ch_old_api) { test_tile_ch(true); }
|
BOOST_AUTO_TEST_CASE(test_tile_ch_old_api) { test_tile_ch(true); }
|
||||||
BOOST_AUTO_TEST_CASE(test_tile_ch_new_api) { test_tile_ch(false); }
|
BOOST_AUTO_TEST_CASE(test_tile_ch_new_api) { test_tile_ch(false); }
|
||||||
|
|
||||||
void test_tile_corech(bool use_string_only_api)
|
|
||||||
{
|
|
||||||
// Note: this tests that given the CoreCH algorithm config option, configuration falls back to
|
|
||||||
// CH and is compatible with CH data
|
|
||||||
using namespace osrm;
|
|
||||||
auto osrm =
|
|
||||||
getOSRM(OSRM_TEST_DATA_DIR "/ch/monaco.osrm", osrm::EngineConfig::Algorithm::CoreCH);
|
|
||||||
validate_tile(osrm, use_string_only_api);
|
|
||||||
}
|
|
||||||
BOOST_AUTO_TEST_CASE(test_tile_corech_old_api) { test_tile_corech(true); }
|
|
||||||
BOOST_AUTO_TEST_CASE(test_tile_corech_new_api) { test_tile_corech(false); }
|
|
||||||
|
|
||||||
void test_tile_mld(bool use_string_only_api)
|
void test_tile_mld(bool use_string_only_api)
|
||||||
{
|
{
|
||||||
using namespace osrm;
|
using namespace osrm;
|
||||||
@ -347,14 +335,6 @@ BOOST_AUTO_TEST_CASE(test_tile_turns_ch_new_api)
|
|||||||
{
|
{
|
||||||
test_tile_turns_ch(osrm::EngineConfig::Algorithm::CH, false);
|
test_tile_turns_ch(osrm::EngineConfig::Algorithm::CH, false);
|
||||||
}
|
}
|
||||||
BOOST_AUTO_TEST_CASE(test_tile_turns_corech_old_api)
|
|
||||||
{
|
|
||||||
test_tile_turns_ch(osrm::EngineConfig::Algorithm::CoreCH, true);
|
|
||||||
}
|
|
||||||
BOOST_AUTO_TEST_CASE(test_tile_turns_corech_new_api)
|
|
||||||
{
|
|
||||||
test_tile_turns_ch(osrm::EngineConfig::Algorithm::CoreCH, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_tile_turns_mld(bool use_string_only_api)
|
void test_tile_turns_mld(bool use_string_only_api)
|
||||||
{
|
{
|
||||||
@ -432,14 +412,6 @@ BOOST_AUTO_TEST_CASE(test_tile_speeds_ch_new_api)
|
|||||||
{
|
{
|
||||||
test_tile_speeds_ch(osrm::EngineConfig::Algorithm::CH, false);
|
test_tile_speeds_ch(osrm::EngineConfig::Algorithm::CH, false);
|
||||||
}
|
}
|
||||||
BOOST_AUTO_TEST_CASE(test_tile_speeds_corech_old_api)
|
|
||||||
{
|
|
||||||
test_tile_speeds_ch(osrm::EngineConfig::Algorithm::CoreCH, true);
|
|
||||||
}
|
|
||||||
BOOST_AUTO_TEST_CASE(test_tile_speeds_corech_new_api)
|
|
||||||
{
|
|
||||||
test_tile_speeds_ch(osrm::EngineConfig::Algorithm::CoreCH, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_tile_speeds_mld(bool use_string_only_api)
|
void test_tile_speeds_mld(bool use_string_only_api)
|
||||||
{
|
{
|
||||||
@ -501,14 +473,6 @@ BOOST_AUTO_TEST_CASE(test_tile_node_ch_new_api)
|
|||||||
{
|
{
|
||||||
test_tile_nodes_ch(osrm::EngineConfig::Algorithm::CH, false);
|
test_tile_nodes_ch(osrm::EngineConfig::Algorithm::CH, false);
|
||||||
}
|
}
|
||||||
BOOST_AUTO_TEST_CASE(test_tile_node_corech_old_api)
|
|
||||||
{
|
|
||||||
test_tile_nodes_ch(osrm::EngineConfig::Algorithm::CoreCH, true);
|
|
||||||
}
|
|
||||||
BOOST_AUTO_TEST_CASE(test_tile_node_corech_new_api)
|
|
||||||
{
|
|
||||||
test_tile_nodes_ch(osrm::EngineConfig::Algorithm::CoreCH, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_tile_nodes_mld(bool use_string_only_api)
|
void test_tile_nodes_mld(bool use_string_only_api)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user