Merge branch 'Project-OSRM:master' into require_radius_when_using_bearings
This commit is contained in:
commit
ba23f5b587
@ -1,5 +1,7 @@
|
|||||||
# Unreleased
|
# Unreleased
|
||||||
- Changes from 5.27.1
|
- Changes from 5.27.1
|
||||||
|
- Features
|
||||||
|
- ADDED: Add support for a default_radius flag. [#6575](https://github.com/Project-OSRM/osrm-backend/pull/6575)
|
||||||
- Build:
|
- Build:
|
||||||
- ADDED: Add CI job which builds OSRM with gcc 12. [#6455](https://github.com/Project-OSRM/osrm-backend/pull/6455)
|
- ADDED: Add CI job which builds OSRM with gcc 12. [#6455](https://github.com/Project-OSRM/osrm-backend/pull/6455)
|
||||||
- CHANGED: Upgrade to clang-tidy 15. [#6439](https://github.com/Project-OSRM/osrm-backend/pull/6439)
|
- CHANGED: Upgrade to clang-tidy 15. [#6439](https://github.com/Project-OSRM/osrm-backend/pull/6439)
|
||||||
@ -8,6 +10,7 @@
|
|||||||
- 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: keep libosrm* in the docker image for downstream linking [#6602](https://github.com/Project-OSRM/osrm-backend/pull/6602)
|
||||||
- CHANGED: Move vector in CSVFilesParser instead copying it. [#6470](https://github.com/Project-OSRM/osrm-backend/pull/6470)
|
- CHANGED: Move vector in CSVFilesParser instead copying it. [#6470](https://github.com/Project-OSRM/osrm-backend/pull/6470)
|
||||||
- REMOVED: Get rid of unused functions in util/json_util.hpp. [#6446](https://github.com/Project-OSRM/osrm-backend/pull/6446)
|
- REMOVED: Get rid of unused functions in util/json_util.hpp. [#6446](https://github.com/Project-OSRM/osrm-backend/pull/6446)
|
||||||
- FIXED: Apply workaround for Conan installation issue on CI. [#6442](https://github.com/Project-OSRM/osrm-backend/pull/6442)
|
- FIXED: Apply workaround for Conan installation issue on CI. [#6442](https://github.com/Project-OSRM/osrm-backend/pull/6442)
|
||||||
@ -18,6 +21,8 @@
|
|||||||
- CHANGED: Make edge metrics strongly typed [#6420](https://github.com/Project-OSRM/osrm-backend/pull/6420)
|
- CHANGED: Make edge metrics strongly typed [#6420](https://github.com/Project-OSRM/osrm-backend/pull/6420)
|
||||||
- FIXED: Typo in file name src/util/timed_historgram.cpp -> src/util/timed_histogram.cpp [#6428](https://github.com/Project-OSRM/osrm-backend/issues/6428)
|
- FIXED: Typo in file name src/util/timed_historgram.cpp -> src/util/timed_histogram.cpp [#6428](https://github.com/Project-OSRM/osrm-backend/issues/6428)
|
||||||
- CHANGED: Replace boost::string_ref with std::string_view [#6433](https://github.com/Project-OSRM/osrm-backend/pull/6433)
|
- CHANGED: Replace boost::string_ref with std::string_view [#6433](https://github.com/Project-OSRM/osrm-backend/pull/6433)
|
||||||
|
- ADDED: Print tracebacks for Lua runtime errors [#6564](https://github.com/Project-OSRM/osrm-backend/pull/6564)
|
||||||
|
- FIXED: Added a variable to preprocessor guard in file osrm-backend/include/util/range_table.hpp to solve build error. [#6596](https://github.com/Project-OSRM/osrm-backend/pull/6596)
|
||||||
- Routing:
|
- Routing:
|
||||||
- FIXED: Fix adding traffic signal penalties during compression [#6419](https://github.com/Project-OSRM/osrm-backend/pull/6419)
|
- FIXED: Fix adding traffic signal penalties during compression [#6419](https://github.com/Project-OSRM/osrm-backend/pull/6419)
|
||||||
# 5.27.1
|
# 5.27.1
|
||||||
|
@ -37,7 +37,7 @@ RUN NPROC=${BUILD_CONCURRENCY:-$(nproc)} && \
|
|||||||
cd ../profiles && \
|
cd ../profiles && \
|
||||||
cp -r * /opt && \
|
cp -r * /opt && \
|
||||||
strip /usr/local/bin/* && \
|
strip /usr/local/bin/* && \
|
||||||
rm -rf /src /usr/local/lib/libosrm*
|
rm -rf /src
|
||||||
|
|
||||||
|
|
||||||
# Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
|
# Multistage build to reduce image size - https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
|
||||||
|
@ -38,6 +38,7 @@ var osrm = new OSRM('network.osrm');
|
|||||||
- `options.max_radius_map_matching` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. radius size supported in map matching query (default: 5).
|
- `options.max_radius_map_matching` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. radius size supported in map matching query (default: 5).
|
||||||
- `options.max_results_nearest` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. results supported in nearest query (default: unlimited).
|
- `options.max_results_nearest` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. results supported in nearest query (default: unlimited).
|
||||||
- `options.max_alternatives` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. number of alternatives supported in alternative routes query (default: 3).
|
- `options.max_alternatives` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Max. number of alternatives supported in alternative routes query (default: 3).
|
||||||
|
- `options.default_radius` **[Number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** Default radius for queries (default: unlimited).
|
||||||
|
|
||||||
### route
|
### route
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ And the relations
|
|||||||
The setting looks perfectly fine at first glance. However, it is not well defined.
|
The setting looks perfectly fine at first glance. However, it is not well defined.
|
||||||
The forbidden right turn could be either a superfluous addition, forbidding the turn `cb` to `be`, or actually refer to the turn `ab` to `bd` to say that a turn is forbidden here.
|
The forbidden right turn could be either a superfluous addition, forbidding the turn `cb` to `be`, or actually refer to the turn `ab` to `bd` to say that a turn is forbidden here.
|
||||||
|
|
||||||
To model turn-restrictions correctly and unique, we need to split segments that contribute to the restriction into the smallest possible parts.
|
To model turn-restrictions correctly and uniquely, we need to split segments that contribute to the restriction into the smallest possible parts.
|
||||||
E.g. the above scenario could correctly be expressed as:
|
E.g. the above scenario could correctly be expressed as:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -360,7 +360,7 @@ When I route I should get
|
|||||||
|
|
||||||
And the test reports `turn right` for the route `a->e`, where before it said `slight right`.
|
And the test reports `turn right` for the route `a->e`, where before it said `slight right`.
|
||||||
|
|
||||||
If you changed the turn angles, obviously you can expect changes in the distinction between `slight right` and `right`.
|
If you change the turn angles, obviously you can expect changes in the distinction between `slight right` and `right`.
|
||||||
In such a case it is, of course, reasonable to change the expected route to report `right` instead of `slight right`. You should consider inspecting the actual turn angles at `b` to see if you feel that change is justified.
|
In such a case it is, of course, reasonable to change the expected route to report `right` instead of `slight right`. You should consider inspecting the actual turn angles at `b` to see if you feel that change is justified.
|
||||||
|
|
||||||
However, you should never adjust the test itself.
|
However, you should never adjust the test itself.
|
||||||
@ -390,9 +390,9 @@ In this case we would see a very slight turn angle. If your change now reports d
|
|||||||
|
|
||||||
### Consider Post-Processing Impacts
|
### Consider Post-Processing Impacts
|
||||||
|
|
||||||
Some changes you might see could look completely unrelated. To understand the impact of your changes, you can make use of the debugging utilities you can finde in `util/debug.hpp` (and potentially other related headers).
|
Some changes you might see could look completely unrelated. To understand the impact of your changes, you can make use of the debugging utilities you can find in `util/debug.hpp` (and potentially other related headers).
|
||||||
|
|
||||||
If your test is inspecting a series of turns (remember, a turn not necessarily equals an instruction), you could see interaction with post-processing.
|
If your test is inspecting a series of turns (remember, a turn does not necessarily equals an instruction), you could see interaction with post-processing.
|
||||||
To see the unprocessed turns, you should print the steps at the end of step assembly (`assembleSteps` in `engine/guidance/assemble_steps.hpp`).
|
To see the unprocessed turns, you should print the steps at the end of step assembly (`assembleSteps` in `engine/guidance/assemble_steps.hpp`).
|
||||||
|
|
||||||
If you see unexpected changes, you can consider adding the `locations` field to your test to study what location a turn is reported at.
|
If you see unexpected changes, you can consider adding the `locations` field to your test to study what location a turn is reported at.
|
||||||
|
@ -22,6 +22,7 @@ Feature: osrm-routed command line options: help
|
|||||||
And stdout should contain "--max-trip-size"
|
And stdout should contain "--max-trip-size"
|
||||||
And stdout should contain "--max-table-size"
|
And stdout should contain "--max-table-size"
|
||||||
And stdout should contain "--max-matching-size"
|
And stdout should contain "--max-matching-size"
|
||||||
|
And stdout should contain "--default-radius"
|
||||||
And it should exit successfully
|
And it should exit successfully
|
||||||
|
|
||||||
Scenario: osrm-routed - Help, short
|
Scenario: osrm-routed - Help, short
|
||||||
@ -42,6 +43,7 @@ Feature: osrm-routed command line options: help
|
|||||||
And stdout should contain "--max-trip-size"
|
And stdout should contain "--max-trip-size"
|
||||||
And stdout should contain "--max-table-size"
|
And stdout should contain "--max-table-size"
|
||||||
And stdout should contain "--max-matching-size"
|
And stdout should contain "--max-matching-size"
|
||||||
|
And stdout should contain "--default-radius"
|
||||||
And it should exit successfully
|
And it should exit successfully
|
||||||
|
|
||||||
Scenario: osrm-routed - Help, long
|
Scenario: osrm-routed - Help, long
|
||||||
@ -62,4 +64,5 @@ Feature: osrm-routed command line options: help
|
|||||||
And stdout should contain "--max-table-size"
|
And stdout should contain "--max-table-size"
|
||||||
And stdout should contain "--max-table-size"
|
And stdout should contain "--max-table-size"
|
||||||
And stdout should contain "--max-matching-size"
|
And stdout should contain "--max-matching-size"
|
||||||
|
And stdout should contain "--default-radius"
|
||||||
And it should exit successfully
|
And it should exit successfully
|
||||||
|
@ -43,12 +43,16 @@ template <typename Algorithm> class Engine final : public EngineInterface
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Engine(const EngineConfig &config)
|
explicit Engine(const EngineConfig &config)
|
||||||
: route_plugin(config.max_locations_viaroute, config.max_alternatives), //
|
: route_plugin(config.max_locations_viaroute,
|
||||||
table_plugin(config.max_locations_distance_table), //
|
config.max_alternatives,
|
||||||
nearest_plugin(config.max_results_nearest), //
|
config.default_radius), //
|
||||||
trip_plugin(config.max_locations_trip), //
|
table_plugin(config.max_locations_distance_table, config.default_radius), //
|
||||||
match_plugin(config.max_locations_map_matching, config.max_radius_map_matching), //
|
nearest_plugin(config.max_results_nearest, config.default_radius), //
|
||||||
tile_plugin() //
|
trip_plugin(config.max_locations_trip, config.default_radius), //
|
||||||
|
match_plugin(config.max_locations_map_matching,
|
||||||
|
config.max_radius_map_matching,
|
||||||
|
config.default_radius), //
|
||||||
|
tile_plugin() //
|
||||||
|
|
||||||
{
|
{
|
||||||
if (config.use_shared_memory)
|
if (config.use_shared_memory)
|
||||||
|
@ -83,6 +83,7 @@ struct EngineConfig final
|
|||||||
int max_locations_map_matching = -1;
|
int max_locations_map_matching = -1;
|
||||||
double max_radius_map_matching = -1.0;
|
double max_radius_map_matching = -1.0;
|
||||||
int max_results_nearest = -1;
|
int max_results_nearest = -1;
|
||||||
|
boost::optional<double> default_radius;
|
||||||
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
|
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
|
||||||
bool use_shared_memory = true;
|
bool use_shared_memory = true;
|
||||||
boost::filesystem::path memory_file;
|
boost::filesystem::path memory_file;
|
||||||
|
@ -20,8 +20,10 @@ class MatchPlugin : public BasePlugin
|
|||||||
using CandidateLists = routing_algorithms::CandidateLists;
|
using CandidateLists = routing_algorithms::CandidateLists;
|
||||||
static const constexpr double RADIUS_MULTIPLIER = 3;
|
static const constexpr double RADIUS_MULTIPLIER = 3;
|
||||||
|
|
||||||
MatchPlugin(const int max_locations_map_matching, const double max_radius_map_matching)
|
MatchPlugin(const int max_locations_map_matching,
|
||||||
: max_locations_map_matching(max_locations_map_matching),
|
const double max_radius_map_matching,
|
||||||
|
const boost::optional<double> default_radius)
|
||||||
|
: BasePlugin(default_radius), max_locations_map_matching(max_locations_map_matching),
|
||||||
max_radius_map_matching(max_radius_map_matching)
|
max_radius_map_matching(max_radius_map_matching)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ namespace osrm::engine::plugins
|
|||||||
class NearestPlugin final : public BasePlugin
|
class NearestPlugin final : public BasePlugin
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit NearestPlugin(const int max_results);
|
explicit NearestPlugin(const int max_results, const boost::optional<double> default_radius);
|
||||||
|
|
||||||
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||||
const api::NearestParameters ¶ms,
|
const api::NearestParameters ¶ms,
|
||||||
|
@ -27,6 +27,10 @@ namespace osrm::engine::plugins
|
|||||||
class BasePlugin
|
class BasePlugin
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
BasePlugin() = default;
|
||||||
|
|
||||||
|
BasePlugin(const boost::optional<double> default_radius_) : default_radius(default_radius_) {}
|
||||||
|
|
||||||
bool CheckAllCoordinates(const std::vector<util::Coordinate> &coordinates) const
|
bool CheckAllCoordinates(const std::vector<util::Coordinate> &coordinates) const
|
||||||
{
|
{
|
||||||
return !std::any_of(
|
return !std::any_of(
|
||||||
@ -237,7 +241,7 @@ class BasePlugin
|
|||||||
phantom_nodes[i] = facade.NearestPhantomNodes(
|
phantom_nodes[i] = facade.NearestPhantomNodes(
|
||||||
parameters.coordinates[i],
|
parameters.coordinates[i],
|
||||||
number_of_results,
|
number_of_results,
|
||||||
use_radiuses ? parameters.radiuses[i] : boost::none,
|
use_radiuses ? parameters.radiuses[i] : default_radius,
|
||||||
use_bearings ? parameters.bearings[i] : boost::none,
|
use_bearings ? parameters.bearings[i] : boost::none,
|
||||||
use_approaches && parameters.approaches[i] ? parameters.approaches[i].get()
|
use_approaches && parameters.approaches[i] ? parameters.approaches[i].get()
|
||||||
: engine::Approach::UNRESTRICTED);
|
: engine::Approach::UNRESTRICTED);
|
||||||
@ -279,7 +283,7 @@ class BasePlugin
|
|||||||
|
|
||||||
alternatives[i] = facade.NearestCandidatesWithAlternativeFromBigComponent(
|
alternatives[i] = facade.NearestCandidatesWithAlternativeFromBigComponent(
|
||||||
parameters.coordinates[i],
|
parameters.coordinates[i],
|
||||||
use_radiuses ? parameters.radiuses[i] : boost::none,
|
use_radiuses ? parameters.radiuses[i] : default_radius,
|
||||||
use_bearings ? parameters.bearings[i] : boost::none,
|
use_bearings ? parameters.bearings[i] : boost::none,
|
||||||
use_approaches && parameters.approaches[i] ? parameters.approaches[i].get()
|
use_approaches && parameters.approaches[i] ? parameters.approaches[i].get()
|
||||||
: engine::Approach::UNRESTRICTED,
|
: engine::Approach::UNRESTRICTED,
|
||||||
@ -320,6 +324,8 @@ class BasePlugin
|
|||||||
return std::string("Could not find a matching segment for coordinate ") +
|
return std::string("Could not find a matching segment for coordinate ") +
|
||||||
std::to_string(missing_index);
|
std::to_string(missing_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const boost::optional<double> default_radius;
|
||||||
};
|
};
|
||||||
} // namespace osrm::engine::plugins
|
} // namespace osrm::engine::plugins
|
||||||
|
|
||||||
|
@ -14,7 +14,8 @@ namespace osrm::engine::plugins
|
|||||||
class TablePlugin final : public BasePlugin
|
class TablePlugin final : public BasePlugin
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit TablePlugin(const int max_locations_distance_table);
|
explicit TablePlugin(const int max_locations_distance_table,
|
||||||
|
const boost::optional<double> default_radius);
|
||||||
|
|
||||||
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||||
const api::TableParameters ¶ms,
|
const api::TableParameters ¶ms,
|
||||||
|
@ -32,7 +32,10 @@ class TripPlugin final : public BasePlugin
|
|||||||
const bool roundtrip) const;
|
const bool roundtrip) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TripPlugin(const int max_locations_trip_) : max_locations_trip(max_locations_trip_) {}
|
explicit TripPlugin(const int max_locations_trip_, boost::optional<double> default_radius)
|
||||||
|
: BasePlugin(default_radius), max_locations_trip(max_locations_trip_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||||
const api::TripParameters ¶meters,
|
const api::TripParameters ¶meters,
|
||||||
|
@ -25,7 +25,9 @@ class ViaRoutePlugin final : public BasePlugin
|
|||||||
const int max_alternatives;
|
const int max_alternatives;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ViaRoutePlugin(int max_locations_viaroute, int max_alternatives);
|
explicit ViaRoutePlugin(int max_locations_viaroute,
|
||||||
|
int max_alternatives,
|
||||||
|
boost::optional<double> default_radius);
|
||||||
|
|
||||||
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
Status HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||||
const api::RouteParameters &route_parameters,
|
const api::RouteParameters &route_parameters,
|
||||||
|
@ -41,10 +41,10 @@ struct LuaScriptingContext final
|
|||||||
bool has_way_function = false;
|
bool has_way_function = false;
|
||||||
bool has_segment_function = false;
|
bool has_segment_function = false;
|
||||||
|
|
||||||
sol::function turn_function;
|
sol::protected_function turn_function;
|
||||||
sol::function way_function;
|
sol::protected_function way_function;
|
||||||
sol::function node_function;
|
sol::protected_function node_function;
|
||||||
sol::function segment_function;
|
sol::protected_function segment_function;
|
||||||
|
|
||||||
int api_version = 4;
|
int api_version = 4;
|
||||||
sol::table profile_table;
|
sol::table profile_table;
|
||||||
|
@ -285,6 +285,7 @@ inline engine_config_ptr argumentsToEngineConfig(const Napi::CallbackInfo &args)
|
|||||||
auto max_results_nearest = params.Get("max_results_nearest");
|
auto max_results_nearest = params.Get("max_results_nearest");
|
||||||
auto max_alternatives = params.Get("max_alternatives");
|
auto max_alternatives = params.Get("max_alternatives");
|
||||||
auto max_radius_map_matching = params.Get("max_radius_map_matching");
|
auto max_radius_map_matching = params.Get("max_radius_map_matching");
|
||||||
|
auto default_radius = params.Get("default_radius");
|
||||||
|
|
||||||
if (!max_locations_trip.IsUndefined() && !max_locations_trip.IsNumber())
|
if (!max_locations_trip.IsUndefined() && !max_locations_trip.IsNumber())
|
||||||
{
|
{
|
||||||
@ -316,6 +317,11 @@ inline engine_config_ptr argumentsToEngineConfig(const Napi::CallbackInfo &args)
|
|||||||
ThrowError(args.Env(), "max_alternatives must be an integral number");
|
ThrowError(args.Env(), "max_alternatives must be an integral number");
|
||||||
return engine_config_ptr();
|
return engine_config_ptr();
|
||||||
}
|
}
|
||||||
|
if (!default_radius.IsUndefined() && !default_radius.IsNumber())
|
||||||
|
{
|
||||||
|
ThrowError(args.Env(), "default_radius must be an integral number");
|
||||||
|
return engine_config_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
if (max_locations_trip.IsNumber())
|
if (max_locations_trip.IsNumber())
|
||||||
engine_config->max_locations_trip = max_locations_trip.ToNumber().Int32Value();
|
engine_config->max_locations_trip = max_locations_trip.ToNumber().Int32Value();
|
||||||
@ -333,6 +339,8 @@ inline engine_config_ptr argumentsToEngineConfig(const Napi::CallbackInfo &args)
|
|||||||
engine_config->max_alternatives = max_alternatives.ToNumber().Int32Value();
|
engine_config->max_alternatives = max_alternatives.ToNumber().Int32Value();
|
||||||
if (max_radius_map_matching.IsNumber())
|
if (max_radius_map_matching.IsNumber())
|
||||||
engine_config->max_radius_map_matching = max_radius_map_matching.ToNumber().DoubleValue();
|
engine_config->max_radius_map_matching = max_radius_map_matching.ToNumber().DoubleValue();
|
||||||
|
if (default_radius.IsNumber())
|
||||||
|
engine_config->default_radius = default_radius.ToNumber().DoubleValue();
|
||||||
|
|
||||||
return engine_config;
|
return engine_config;
|
||||||
}
|
}
|
||||||
|
@ -79,10 +79,10 @@ template <unsigned BLOCK_SIZE, storage::Ownership Ownership> class RangeTable
|
|||||||
unsigned last_length = 0;
|
unsigned last_length = 0;
|
||||||
unsigned lengths_prefix_sum = 0;
|
unsigned lengths_prefix_sum = 0;
|
||||||
unsigned block_idx = 0;
|
unsigned block_idx = 0;
|
||||||
unsigned block_counter = 0;
|
|
||||||
BlockT block;
|
BlockT block;
|
||||||
#ifndef BOOST_ASSERT_IS_VOID
|
#ifndef BOOST_ASSERT_IS_VOID
|
||||||
unsigned block_sum = 0;
|
unsigned block_sum = 0;
|
||||||
|
unsigned block_counter = 0;
|
||||||
#endif
|
#endif
|
||||||
for (const unsigned l : lengths)
|
for (const unsigned l : lengths)
|
||||||
{
|
{
|
||||||
@ -109,7 +109,9 @@ template <unsigned BLOCK_SIZE, storage::Ownership Ownership> class RangeTable
|
|||||||
if (BLOCK_SIZE == block_idx)
|
if (BLOCK_SIZE == block_idx)
|
||||||
{
|
{
|
||||||
diff_blocks.push_back(block);
|
diff_blocks.push_back(block);
|
||||||
|
#ifndef BOOST_ASSERT_IS_VOID
|
||||||
block_counter++;
|
block_counter++;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can only store strings with length 255
|
// we can only store strings with length 255
|
||||||
|
@ -6,3 +6,12 @@
|
|||||||
# #1 0x7f7ae595d13e (/usr/lib/x86_64-linux-gnu/libtbb.so.2+0x2213e)
|
# #1 0x7f7ae595d13e (/usr/lib/x86_64-linux-gnu/libtbb.so.2+0x2213e)
|
||||||
|
|
||||||
leak:libtbb.so
|
leak:libtbb.so
|
||||||
|
|
||||||
|
# The extract-tests leak some memory in the tests to confirm that
|
||||||
|
# lua errors print tracebacks.
|
||||||
|
# This appears to be because when these tests throw exceptions, the
|
||||||
|
# osmium objects being processed are not freed. In production this doesn't
|
||||||
|
# matter, as the exceptions bring down the entire osrm-extract process. In the
|
||||||
|
# tests, we catch the error to make sure it occurs, which is why the
|
||||||
|
# leaksanitizer flags it.
|
||||||
|
leak:extract-tests
|
@ -181,24 +181,29 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
|||||||
if (tidied.parameters.radiuses.empty())
|
if (tidied.parameters.radiuses.empty())
|
||||||
{
|
{
|
||||||
search_radiuses.resize(tidied.parameters.coordinates.size(),
|
search_radiuses.resize(tidied.parameters.coordinates.size(),
|
||||||
routing_algorithms::DEFAULT_GPS_PRECISION * RADIUS_MULTIPLIER);
|
default_radius.has_value()
|
||||||
|
? *default_radius
|
||||||
|
: routing_algorithms::DEFAULT_GPS_PRECISION * RADIUS_MULTIPLIER);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
search_radiuses.resize(tidied.parameters.coordinates.size());
|
search_radiuses.resize(tidied.parameters.coordinates.size());
|
||||||
std::transform(tidied.parameters.radiuses.begin(),
|
std::transform(
|
||||||
tidied.parameters.radiuses.end(),
|
tidied.parameters.radiuses.begin(),
|
||||||
search_radiuses.begin(),
|
tidied.parameters.radiuses.end(),
|
||||||
[](const boost::optional<double> &maybe_radius) {
|
search_radiuses.begin(),
|
||||||
if (maybe_radius)
|
[default_radius = this->default_radius](const boost::optional<double> &maybe_radius) {
|
||||||
{
|
if (maybe_radius)
|
||||||
return *maybe_radius * RADIUS_MULTIPLIER;
|
{
|
||||||
}
|
return *maybe_radius * RADIUS_MULTIPLIER;
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
return routing_algorithms::DEFAULT_GPS_PRECISION * RADIUS_MULTIPLIER;
|
{
|
||||||
}
|
return default_radius.has_value()
|
||||||
});
|
? *default_radius
|
||||||
|
: routing_algorithms::DEFAULT_GPS_PRECISION * RADIUS_MULTIPLIER;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto candidates_lists =
|
auto candidates_lists =
|
||||||
|
@ -10,7 +10,10 @@
|
|||||||
namespace osrm::engine::plugins
|
namespace osrm::engine::plugins
|
||||||
{
|
{
|
||||||
|
|
||||||
NearestPlugin::NearestPlugin(const int max_results_) : max_results{max_results_} {}
|
NearestPlugin::NearestPlugin(const int max_results_, const boost::optional<double> default_radius_)
|
||||||
|
: BasePlugin(default_radius_), max_results{max_results_}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Status NearestPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
Status NearestPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||||
const api::NearestParameters ¶ms,
|
const api::NearestParameters ¶ms,
|
||||||
|
@ -14,8 +14,9 @@
|
|||||||
namespace osrm::engine::plugins
|
namespace osrm::engine::plugins
|
||||||
{
|
{
|
||||||
|
|
||||||
TablePlugin::TablePlugin(const int max_locations_distance_table)
|
TablePlugin::TablePlugin(const int max_locations_distance_table,
|
||||||
: max_locations_distance_table(max_locations_distance_table)
|
const boost::optional<double> default_radius)
|
||||||
|
: BasePlugin(default_radius), max_locations_distance_table(max_locations_distance_table)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,11 @@
|
|||||||
namespace osrm::engine::plugins
|
namespace osrm::engine::plugins
|
||||||
{
|
{
|
||||||
|
|
||||||
ViaRoutePlugin::ViaRoutePlugin(int max_locations_viaroute, int max_alternatives)
|
ViaRoutePlugin::ViaRoutePlugin(int max_locations_viaroute,
|
||||||
: max_locations_viaroute(max_locations_viaroute), max_alternatives(max_alternatives)
|
int max_alternatives,
|
||||||
|
boost::optional<double> default_radius)
|
||||||
|
: BasePlugin(default_radius), max_locations_viaroute(max_locations_viaroute),
|
||||||
|
max_alternatives(max_alternatives)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +91,19 @@ struct to_lua_object : public boost::static_visitor<sol::object>
|
|||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
// Handle a lua error thrown in a protected function by printing the traceback and bubbling
|
||||||
|
// exception up to caller. Lua errors are generally unrecoverable, so this exception should not be
|
||||||
|
// caught but instead should terminate the process. The point of having this error handler rather
|
||||||
|
// than just using unprotected Lua functions which terminate the process automatically is that this
|
||||||
|
// function provides more useful error messages including Lua tracebacks and line numbers.
|
||||||
|
void handle_lua_error(sol::protected_function_result &luares)
|
||||||
|
{
|
||||||
|
sol::error luaerr = luares;
|
||||||
|
std::string msg = luaerr.what();
|
||||||
|
std::cerr << msg << std::endl;
|
||||||
|
throw util::exception("Lua error (see stderr for traceback)");
|
||||||
|
}
|
||||||
|
|
||||||
Sol2ScriptingEnvironment::Sol2ScriptingEnvironment(
|
Sol2ScriptingEnvironment::Sol2ScriptingEnvironment(
|
||||||
const std::string &file_name,
|
const std::string &file_name,
|
||||||
const std::vector<boost::filesystem::path> &location_dependent_data_paths)
|
const std::vector<boost::filesystem::path> &location_dependent_data_paths)
|
||||||
@ -550,10 +563,16 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
|||||||
std::numeric_limits<TurnPenalty::value_type>::max());
|
std::numeric_limits<TurnPenalty::value_type>::max());
|
||||||
|
|
||||||
// call initialize function
|
// call initialize function
|
||||||
sol::function setup_function = function_table.value()["setup"];
|
sol::protected_function setup_function = function_table.value()["setup"];
|
||||||
if (!setup_function.valid())
|
if (!setup_function.valid())
|
||||||
throw util::exception("Profile must have an setup() function.");
|
throw util::exception("Profile must have an setup() function.");
|
||||||
sol::optional<sol::table> profile_table = setup_function();
|
|
||||||
|
auto setup_result = setup_function();
|
||||||
|
|
||||||
|
if (!setup_result.valid())
|
||||||
|
handle_lua_error(setup_result);
|
||||||
|
|
||||||
|
sol::optional<sol::table> profile_table = setup_result;
|
||||||
if (profile_table == sol::nullopt)
|
if (profile_table == sol::nullopt)
|
||||||
throw util::exception("Profile setup() must return a table.");
|
throw util::exception("Profile setup() must return a table.");
|
||||||
else
|
else
|
||||||
@ -1123,7 +1142,9 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn)
|
|||||||
case 2:
|
case 2:
|
||||||
if (context.has_turn_penalty_function)
|
if (context.has_turn_penalty_function)
|
||||||
{
|
{
|
||||||
context.turn_function(context.profile_table, std::ref(turn));
|
auto luares = context.turn_function(context.profile_table, std::ref(turn));
|
||||||
|
if (!luares.valid())
|
||||||
|
handle_lua_error(luares);
|
||||||
|
|
||||||
// Turn weight falls back to the duration value in deciseconds
|
// Turn weight falls back to the duration value in deciseconds
|
||||||
// or uses the extracted unit-less weight value
|
// or uses the extracted unit-less weight value
|
||||||
@ -1138,7 +1159,9 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn)
|
|||||||
case 1:
|
case 1:
|
||||||
if (context.has_turn_penalty_function)
|
if (context.has_turn_penalty_function)
|
||||||
{
|
{
|
||||||
context.turn_function(std::ref(turn));
|
auto luares = context.turn_function(std::ref(turn));
|
||||||
|
if (!luares.valid())
|
||||||
|
handle_lua_error(luares);
|
||||||
|
|
||||||
// Turn weight falls back to the duration value in deciseconds
|
// Turn weight falls back to the duration value in deciseconds
|
||||||
// or uses the extracted unit-less weight value
|
// or uses the extracted unit-less weight value
|
||||||
@ -1184,24 +1207,28 @@ void Sol2ScriptingEnvironment::ProcessSegment(ExtractionSegment &segment)
|
|||||||
|
|
||||||
if (context.has_segment_function)
|
if (context.has_segment_function)
|
||||||
{
|
{
|
||||||
|
sol::protected_function_result luares;
|
||||||
switch (context.api_version)
|
switch (context.api_version)
|
||||||
{
|
{
|
||||||
case 4:
|
case 4:
|
||||||
case 3:
|
case 3:
|
||||||
case 2:
|
case 2:
|
||||||
context.segment_function(context.profile_table, std::ref(segment));
|
luares = context.segment_function(context.profile_table, std::ref(segment));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
context.segment_function(std::ref(segment));
|
luares = context.segment_function(std::ref(segment));
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
context.segment_function(std::ref(segment.source),
|
luares = context.segment_function(std::ref(segment.source),
|
||||||
std::ref(segment.target),
|
std::ref(segment.target),
|
||||||
segment.distance,
|
segment.distance,
|
||||||
segment.duration);
|
segment.duration);
|
||||||
segment.weight = segment.duration; // back-compatibility fallback to duration
|
segment.weight = segment.duration; // back-compatibility fallback to duration
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!luares.valid())
|
||||||
|
handle_lua_error(luares);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1211,20 +1238,27 @@ void LuaScriptingContext::ProcessNode(const osmium::Node &node,
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(state.lua_state() != nullptr);
|
BOOST_ASSERT(state.lua_state() != nullptr);
|
||||||
|
|
||||||
|
sol::protected_function_result luares;
|
||||||
|
|
||||||
|
// TODO check for api version, make sure luares is always set
|
||||||
switch (api_version)
|
switch (api_version)
|
||||||
{
|
{
|
||||||
case 4:
|
case 4:
|
||||||
case 3:
|
case 3:
|
||||||
node_function(profile_table, std::cref(node), std::ref(result), std::cref(relations));
|
luares =
|
||||||
|
node_function(profile_table, std::cref(node), std::ref(result), std::cref(relations));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
node_function(profile_table, std::cref(node), std::ref(result));
|
luares = node_function(profile_table, std::cref(node), std::ref(result));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
case 0:
|
case 0:
|
||||||
node_function(std::cref(node), std::ref(result));
|
luares = node_function(std::cref(node), std::ref(result));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!luares.valid())
|
||||||
|
handle_lua_error(luares);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaScriptingContext::ProcessWay(const osmium::Way &way,
|
void LuaScriptingContext::ProcessWay(const osmium::Way &way,
|
||||||
@ -1233,20 +1267,27 @@ void LuaScriptingContext::ProcessWay(const osmium::Way &way,
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(state.lua_state() != nullptr);
|
BOOST_ASSERT(state.lua_state() != nullptr);
|
||||||
|
|
||||||
|
sol::protected_function_result luares;
|
||||||
|
|
||||||
|
// TODO check for api version, make sure luares is always set
|
||||||
switch (api_version)
|
switch (api_version)
|
||||||
{
|
{
|
||||||
case 4:
|
case 4:
|
||||||
case 3:
|
case 3:
|
||||||
way_function(profile_table, std::cref(way), std::ref(result), std::cref(relations));
|
luares =
|
||||||
|
way_function(profile_table, std::cref(way), std::ref(result), std::cref(relations));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
way_function(profile_table, std::cref(way), std::ref(result));
|
luares = way_function(profile_table, std::cref(way), std::ref(result));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
case 0:
|
case 0:
|
||||||
way_function(std::cref(way), std::ref(result));
|
luares = way_function(std::cref(way), std::ref(result));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!luares.valid())
|
||||||
|
handle_lua_error(luares);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace osrm::extractor
|
} // namespace osrm::extractor
|
||||||
|
@ -81,6 +81,7 @@ Napi::Object Engine::Init(Napi::Env env, Napi::Object exports)
|
|||||||
* @param {Number} [options.max_radius_map_matching] Max. radius size supported in map matching query (default: 5).
|
* @param {Number} [options.max_radius_map_matching] Max. radius size supported in map matching query (default: 5).
|
||||||
* @param {Number} [options.max_results_nearest] Max. results supported in nearest query (default: unlimited).
|
* @param {Number} [options.max_results_nearest] Max. results supported in nearest query (default: unlimited).
|
||||||
* @param {Number} [options.max_alternatives] Max. number of alternatives supported in alternative routes query (default: 3).
|
* @param {Number} [options.max_alternatives] Max. number of alternatives supported in alternative routes query (default: 3).
|
||||||
|
* @param {Number} [options.default_radius] Default radius for queries (default: unlimited).
|
||||||
*
|
*
|
||||||
* @class OSRM
|
* @class OSRM
|
||||||
*
|
*
|
||||||
|
@ -147,7 +147,10 @@ inline unsigned generateServerProgramOptions(const int argc,
|
|||||||
"Max. number of alternatives supported in the MLD route query") //
|
"Max. number of alternatives supported in the MLD route query") //
|
||||||
("max-matching-radius",
|
("max-matching-radius",
|
||||||
value<double>(&config.max_radius_map_matching)->default_value(-1.0),
|
value<double>(&config.max_radius_map_matching)->default_value(-1.0),
|
||||||
"Max. radius size supported in map matching query. Default: unlimited.");
|
"Max. radius size supported in map matching query. Default: unlimited.") //
|
||||||
|
("default-radius",
|
||||||
|
value<boost::optional<double>>(&config.default_radius),
|
||||||
|
"Default radius size for queries. Default: unlimited.");
|
||||||
|
|
||||||
// hidden options, will be allowed on command line, but will not be shown to the user
|
// hidden options, will be allowed on command line, but will not be shown to the user
|
||||||
boost::program_options::options_description hidden_options("Hidden options");
|
boost::program_options::options_description hidden_options("Hidden options");
|
||||||
|
140
test/data/profiles/bad_node.lua
Normal file
140
test/data/profiles/bad_node.lua
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
-- copy of testbot with process_node throwing a runtime error
|
||||||
|
|
||||||
|
api_version = 4
|
||||||
|
|
||||||
|
function setup()
|
||||||
|
return {
|
||||||
|
properties = {
|
||||||
|
continue_straight_at_waypoint = true,
|
||||||
|
max_speed_for_map_matching = 30/3.6, --km -> m/s
|
||||||
|
weight_name = 'duration',
|
||||||
|
process_call_tagless_node = false,
|
||||||
|
u_turn_penalty = 20,
|
||||||
|
traffic_light_penalty = 7, -- seconds
|
||||||
|
use_turn_restrictions = true
|
||||||
|
},
|
||||||
|
|
||||||
|
classes = {"motorway", "toll", "TooWords2"},
|
||||||
|
|
||||||
|
excludable = {
|
||||||
|
{["motorway"] = true},
|
||||||
|
{["toll"] = true},
|
||||||
|
{["motorway"] = true, ["toll"] = true}
|
||||||
|
},
|
||||||
|
|
||||||
|
default_speed = 24,
|
||||||
|
speeds = {
|
||||||
|
primary = 36,
|
||||||
|
secondary = 18,
|
||||||
|
tertiary = 12,
|
||||||
|
steps = 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_node (profile, node, result)
|
||||||
|
if (2 < nil) then
|
||||||
|
print("2 is less than nil")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- check if node is a traffic light
|
||||||
|
-- TODO: a way to set the penalty value
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_way (profile, way, result)
|
||||||
|
local highway = way:get_value_by_key("highway")
|
||||||
|
local toll = way:get_value_by_key("toll")
|
||||||
|
local name = way:get_value_by_key("name")
|
||||||
|
local oneway = way:get_value_by_key("oneway")
|
||||||
|
local route = way:get_value_by_key("route")
|
||||||
|
local duration = way:get_value_by_key("duration")
|
||||||
|
local maxspeed = tonumber(way:get_value_by_key ( "maxspeed"))
|
||||||
|
local maxspeed_forward = tonumber(way:get_value_by_key( "maxspeed:forward"))
|
||||||
|
local maxspeed_backward = tonumber(way:get_value_by_key( "maxspeed:backward"))
|
||||||
|
local junction = way:get_value_by_key("junction")
|
||||||
|
|
||||||
|
if name then
|
||||||
|
result.name = name
|
||||||
|
end
|
||||||
|
|
||||||
|
result.forward_mode = mode.driving
|
||||||
|
result.backward_mode = mode.driving
|
||||||
|
|
||||||
|
if duration and durationIsValid(duration) then
|
||||||
|
result.duration = math.max( 1, parseDuration(duration) )
|
||||||
|
result.forward_mode = mode.route
|
||||||
|
result.backward_mode = mode.route
|
||||||
|
else
|
||||||
|
local speed_forw = profile.speeds[highway] or profile.default_speed
|
||||||
|
local speed_back = speed_forw
|
||||||
|
|
||||||
|
if highway == "river" then
|
||||||
|
local temp_speed = speed_forw
|
||||||
|
result.forward_mode = mode.river_down
|
||||||
|
result.backward_mode = mode.river_up
|
||||||
|
speed_forw = temp_speed*1.5
|
||||||
|
speed_back = temp_speed/1.5
|
||||||
|
elseif highway == "steps" then
|
||||||
|
result.forward_mode = mode.steps_down
|
||||||
|
result.backward_mode = mode.steps_up
|
||||||
|
end
|
||||||
|
|
||||||
|
if maxspeed_forward ~= nil and maxspeed_forward > 0 then
|
||||||
|
speed_forw = maxspeed_forward
|
||||||
|
else
|
||||||
|
if maxspeed ~= nil and maxspeed > 0 and speed_forw > maxspeed then
|
||||||
|
speed_forw = maxspeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if maxspeed_backward ~= nil and maxspeed_backward > 0 then
|
||||||
|
speed_back = maxspeed_backward
|
||||||
|
else
|
||||||
|
if maxspeed ~=nil and maxspeed > 0 and speed_back > maxspeed then
|
||||||
|
speed_back = maxspeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result.forward_speed = speed_forw
|
||||||
|
result.backward_speed = speed_back
|
||||||
|
end
|
||||||
|
|
||||||
|
if oneway == "no" or oneway == "0" or oneway == "false" then
|
||||||
|
-- nothing to do
|
||||||
|
elseif oneway == "-1" then
|
||||||
|
result.forward_mode = mode.inaccessible
|
||||||
|
elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" then
|
||||||
|
result.backward_mode = mode.inaccessible
|
||||||
|
end
|
||||||
|
|
||||||
|
if highway == 'motorway' then
|
||||||
|
result.forward_classes["motorway"] = true
|
||||||
|
result.backward_classes["motorway"] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if toll == "yes" then
|
||||||
|
result.forward_classes["toll"] = true
|
||||||
|
result.backward_classes["toll"] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if junction == 'roundabout' then
|
||||||
|
result.roundabout = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_turn (profile, turn)
|
||||||
|
if turn.is_u_turn then
|
||||||
|
turn.duration = turn.duration + profile.properties.u_turn_penalty
|
||||||
|
turn.weight = turn.weight + profile.properties.u_turn_penalty
|
||||||
|
end
|
||||||
|
if turn.has_traffic_light then
|
||||||
|
turn.duration = turn.duration + profile.properties.traffic_light_penalty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
setup = setup,
|
||||||
|
process_way = process_way,
|
||||||
|
process_node = process_node,
|
||||||
|
process_turn = process_turn
|
||||||
|
}
|
143
test/data/profiles/bad_segment.lua
Normal file
143
test/data/profiles/bad_segment.lua
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
-- A copy of testbot with process_segment throwing a runtime error
|
||||||
|
|
||||||
|
api_version = 4
|
||||||
|
|
||||||
|
function setup()
|
||||||
|
return {
|
||||||
|
properties = {
|
||||||
|
continue_straight_at_waypoint = true,
|
||||||
|
max_speed_for_map_matching = 30/3.6, --km -> m/s
|
||||||
|
weight_name = 'duration',
|
||||||
|
process_call_tagless_node = false,
|
||||||
|
u_turn_penalty = 20,
|
||||||
|
traffic_light_penalty = 7, -- seconds
|
||||||
|
use_turn_restrictions = true
|
||||||
|
},
|
||||||
|
|
||||||
|
classes = {"motorway", "toll", "TooWords2"},
|
||||||
|
|
||||||
|
excludable = {
|
||||||
|
{["motorway"] = true},
|
||||||
|
{["toll"] = true},
|
||||||
|
{["motorway"] = true, ["toll"] = true}
|
||||||
|
},
|
||||||
|
|
||||||
|
default_speed = 24,
|
||||||
|
speeds = {
|
||||||
|
primary = 36,
|
||||||
|
secondary = 18,
|
||||||
|
tertiary = 12,
|
||||||
|
steps = 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_node (profile, node, result)
|
||||||
|
-- check if node is a traffic light
|
||||||
|
-- TODO: a way to set the penalty value
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_way (profile, way, result)
|
||||||
|
local highway = way:get_value_by_key("highway")
|
||||||
|
local toll = way:get_value_by_key("toll")
|
||||||
|
local name = way:get_value_by_key("name")
|
||||||
|
local oneway = way:get_value_by_key("oneway")
|
||||||
|
local route = way:get_value_by_key("route")
|
||||||
|
local duration = way:get_value_by_key("duration")
|
||||||
|
local maxspeed = tonumber(way:get_value_by_key ( "maxspeed"))
|
||||||
|
local maxspeed_forward = tonumber(way:get_value_by_key( "maxspeed:forward"))
|
||||||
|
local maxspeed_backward = tonumber(way:get_value_by_key( "maxspeed:backward"))
|
||||||
|
local junction = way:get_value_by_key("junction")
|
||||||
|
|
||||||
|
if name then
|
||||||
|
result.name = name
|
||||||
|
end
|
||||||
|
|
||||||
|
result.forward_mode = mode.driving
|
||||||
|
result.backward_mode = mode.driving
|
||||||
|
|
||||||
|
if duration and durationIsValid(duration) then
|
||||||
|
result.duration = math.max( 1, parseDuration(duration) )
|
||||||
|
result.forward_mode = mode.route
|
||||||
|
result.backward_mode = mode.route
|
||||||
|
else
|
||||||
|
local speed_forw = profile.speeds[highway] or profile.default_speed
|
||||||
|
local speed_back = speed_forw
|
||||||
|
|
||||||
|
if highway == "river" then
|
||||||
|
local temp_speed = speed_forw
|
||||||
|
result.forward_mode = mode.river_down
|
||||||
|
result.backward_mode = mode.river_up
|
||||||
|
speed_forw = temp_speed*1.5
|
||||||
|
speed_back = temp_speed/1.5
|
||||||
|
elseif highway == "steps" then
|
||||||
|
result.forward_mode = mode.steps_down
|
||||||
|
result.backward_mode = mode.steps_up
|
||||||
|
end
|
||||||
|
|
||||||
|
if maxspeed_forward ~= nil and maxspeed_forward > 0 then
|
||||||
|
speed_forw = maxspeed_forward
|
||||||
|
else
|
||||||
|
if maxspeed ~= nil and maxspeed > 0 and speed_forw > maxspeed then
|
||||||
|
speed_forw = maxspeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if maxspeed_backward ~= nil and maxspeed_backward > 0 then
|
||||||
|
speed_back = maxspeed_backward
|
||||||
|
else
|
||||||
|
if maxspeed ~=nil and maxspeed > 0 and speed_back > maxspeed then
|
||||||
|
speed_back = maxspeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result.forward_speed = speed_forw
|
||||||
|
result.backward_speed = speed_back
|
||||||
|
end
|
||||||
|
|
||||||
|
if oneway == "no" or oneway == "0" or oneway == "false" then
|
||||||
|
-- nothing to do
|
||||||
|
elseif oneway == "-1" then
|
||||||
|
result.forward_mode = mode.inaccessible
|
||||||
|
elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" then
|
||||||
|
result.backward_mode = mode.inaccessible
|
||||||
|
end
|
||||||
|
|
||||||
|
if highway == 'motorway' then
|
||||||
|
result.forward_classes["motorway"] = true
|
||||||
|
result.backward_classes["motorway"] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if toll == "yes" then
|
||||||
|
result.forward_classes["toll"] = true
|
||||||
|
result.backward_classes["toll"] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if junction == 'roundabout' then
|
||||||
|
result.roundabout = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_turn (profile, turn)
|
||||||
|
if turn.is_u_turn then
|
||||||
|
turn.duration = turn.duration + profile.properties.u_turn_penalty
|
||||||
|
turn.weight = turn.weight + profile.properties.u_turn_penalty
|
||||||
|
end
|
||||||
|
if turn.has_traffic_light then
|
||||||
|
turn.duration = turn.duration + profile.properties.traffic_light_penalty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_segment (profile, segment)
|
||||||
|
if (2 < nil) then
|
||||||
|
print("2 is less than nil")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
setup = setup,
|
||||||
|
process_way = process_way,
|
||||||
|
process_node = process_node,
|
||||||
|
process_turn = process_turn,
|
||||||
|
process_segment = process_segment
|
||||||
|
}
|
140
test/data/profiles/bad_setup.lua
Normal file
140
test/data/profiles/bad_setup.lua
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
-- Copy of testbot profile, with setup throwing a runtime error
|
||||||
|
|
||||||
|
api_version = 4
|
||||||
|
|
||||||
|
function setup()
|
||||||
|
if (2 < nil) then -- arithmetic with nil should error
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
properties = {
|
||||||
|
continue_straight_at_waypoint = true,
|
||||||
|
max_speed_for_map_matching = 30/3.6, --km -> m/s
|
||||||
|
weight_name = 'duration',
|
||||||
|
process_call_tagless_node = false,
|
||||||
|
u_turn_penalty = 20,
|
||||||
|
traffic_light_penalty = 7, -- seconds
|
||||||
|
use_turn_restrictions = true
|
||||||
|
},
|
||||||
|
|
||||||
|
classes = {"motorway", "toll", "TooWords2"},
|
||||||
|
|
||||||
|
excludable = {
|
||||||
|
{["motorway"] = true},
|
||||||
|
{["toll"] = true},
|
||||||
|
{["motorway"] = true, ["toll"] = true}
|
||||||
|
},
|
||||||
|
|
||||||
|
default_speed = 24,
|
||||||
|
speeds = {
|
||||||
|
primary = 36,
|
||||||
|
secondary = 18,
|
||||||
|
tertiary = 12,
|
||||||
|
steps = 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_node (profile, node, result)
|
||||||
|
-- check if node is a traffic light
|
||||||
|
-- TODO: a way to set the penalty value
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_way (profile, way, result)
|
||||||
|
local highway = way:get_value_by_key("highway")
|
||||||
|
local toll = way:get_value_by_key("toll")
|
||||||
|
local name = way:get_value_by_key("name")
|
||||||
|
local oneway = way:get_value_by_key("oneway")
|
||||||
|
local route = way:get_value_by_key("route")
|
||||||
|
local duration = way:get_value_by_key("duration")
|
||||||
|
local maxspeed = tonumber(way:get_value_by_key ( "maxspeed"))
|
||||||
|
local maxspeed_forward = tonumber(way:get_value_by_key( "maxspeed:forward"))
|
||||||
|
local maxspeed_backward = tonumber(way:get_value_by_key( "maxspeed:backward"))
|
||||||
|
local junction = way:get_value_by_key("junction")
|
||||||
|
|
||||||
|
if name then
|
||||||
|
result.name = name
|
||||||
|
end
|
||||||
|
|
||||||
|
result.forward_mode = mode.driving
|
||||||
|
result.backward_mode = mode.driving
|
||||||
|
|
||||||
|
if duration and durationIsValid(duration) then
|
||||||
|
result.duration = math.max( 1, parseDuration(duration) )
|
||||||
|
result.forward_mode = mode.route
|
||||||
|
result.backward_mode = mode.route
|
||||||
|
else
|
||||||
|
local speed_forw = profile.speeds[highway] or profile.default_speed
|
||||||
|
local speed_back = speed_forw
|
||||||
|
|
||||||
|
if highway == "river" then
|
||||||
|
local temp_speed = speed_forw
|
||||||
|
result.forward_mode = mode.river_down
|
||||||
|
result.backward_mode = mode.river_up
|
||||||
|
speed_forw = temp_speed*1.5
|
||||||
|
speed_back = temp_speed/1.5
|
||||||
|
elseif highway == "steps" then
|
||||||
|
result.forward_mode = mode.steps_down
|
||||||
|
result.backward_mode = mode.steps_up
|
||||||
|
end
|
||||||
|
|
||||||
|
if maxspeed_forward ~= nil and maxspeed_forward > 0 then
|
||||||
|
speed_forw = maxspeed_forward
|
||||||
|
else
|
||||||
|
if maxspeed ~= nil and maxspeed > 0 and speed_forw > maxspeed then
|
||||||
|
speed_forw = maxspeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if maxspeed_backward ~= nil and maxspeed_backward > 0 then
|
||||||
|
speed_back = maxspeed_backward
|
||||||
|
else
|
||||||
|
if maxspeed ~=nil and maxspeed > 0 and speed_back > maxspeed then
|
||||||
|
speed_back = maxspeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result.forward_speed = speed_forw
|
||||||
|
result.backward_speed = speed_back
|
||||||
|
end
|
||||||
|
|
||||||
|
if oneway == "no" or oneway == "0" or oneway == "false" then
|
||||||
|
-- nothing to do
|
||||||
|
elseif oneway == "-1" then
|
||||||
|
result.forward_mode = mode.inaccessible
|
||||||
|
elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" then
|
||||||
|
result.backward_mode = mode.inaccessible
|
||||||
|
end
|
||||||
|
|
||||||
|
if highway == 'motorway' then
|
||||||
|
result.forward_classes["motorway"] = true
|
||||||
|
result.backward_classes["motorway"] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if toll == "yes" then
|
||||||
|
result.forward_classes["toll"] = true
|
||||||
|
result.backward_classes["toll"] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if junction == 'roundabout' then
|
||||||
|
result.roundabout = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_turn (profile, turn)
|
||||||
|
if turn.is_u_turn then
|
||||||
|
turn.duration = turn.duration + profile.properties.u_turn_penalty
|
||||||
|
turn.weight = turn.weight + profile.properties.u_turn_penalty
|
||||||
|
end
|
||||||
|
if turn.has_traffic_light then
|
||||||
|
turn.duration = turn.duration + profile.properties.traffic_light_penalty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
setup = setup,
|
||||||
|
process_way = process_way,
|
||||||
|
process_node = process_node,
|
||||||
|
process_turn = process_turn
|
||||||
|
}
|
140
test/data/profiles/bad_turn.lua
Normal file
140
test/data/profiles/bad_turn.lua
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
-- a copy of testbot with process_turn throwing an error
|
||||||
|
|
||||||
|
api_version = 4
|
||||||
|
|
||||||
|
function setup()
|
||||||
|
return {
|
||||||
|
properties = {
|
||||||
|
continue_straight_at_waypoint = true,
|
||||||
|
max_speed_for_map_matching = 30/3.6, --km -> m/s
|
||||||
|
weight_name = 'duration',
|
||||||
|
process_call_tagless_node = false,
|
||||||
|
u_turn_penalty = 20,
|
||||||
|
traffic_light_penalty = 7, -- seconds
|
||||||
|
use_turn_restrictions = true
|
||||||
|
},
|
||||||
|
|
||||||
|
classes = {"motorway", "toll", "TooWords2"},
|
||||||
|
|
||||||
|
excludable = {
|
||||||
|
{["motorway"] = true},
|
||||||
|
{["toll"] = true},
|
||||||
|
{["motorway"] = true, ["toll"] = true}
|
||||||
|
},
|
||||||
|
|
||||||
|
default_speed = 24,
|
||||||
|
speeds = {
|
||||||
|
primary = 36,
|
||||||
|
secondary = 18,
|
||||||
|
tertiary = 12,
|
||||||
|
steps = 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_node (profile, node, result)
|
||||||
|
-- check if node is a traffic light
|
||||||
|
-- TODO: a way to set the penalty value
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_way (profile, way, result)
|
||||||
|
local highway = way:get_value_by_key("highway")
|
||||||
|
local toll = way:get_value_by_key("toll")
|
||||||
|
local name = way:get_value_by_key("name")
|
||||||
|
local oneway = way:get_value_by_key("oneway")
|
||||||
|
local route = way:get_value_by_key("route")
|
||||||
|
local duration = way:get_value_by_key("duration")
|
||||||
|
local maxspeed = tonumber(way:get_value_by_key ( "maxspeed"))
|
||||||
|
local maxspeed_forward = tonumber(way:get_value_by_key( "maxspeed:forward"))
|
||||||
|
local maxspeed_backward = tonumber(way:get_value_by_key( "maxspeed:backward"))
|
||||||
|
local junction = way:get_value_by_key("junction")
|
||||||
|
|
||||||
|
if name then
|
||||||
|
result.name = name
|
||||||
|
end
|
||||||
|
|
||||||
|
result.forward_mode = mode.driving
|
||||||
|
result.backward_mode = mode.driving
|
||||||
|
|
||||||
|
if duration and durationIsValid(duration) then
|
||||||
|
result.duration = math.max( 1, parseDuration(duration) )
|
||||||
|
result.forward_mode = mode.route
|
||||||
|
result.backward_mode = mode.route
|
||||||
|
else
|
||||||
|
local speed_forw = profile.speeds[highway] or profile.default_speed
|
||||||
|
local speed_back = speed_forw
|
||||||
|
|
||||||
|
if highway == "river" then
|
||||||
|
local temp_speed = speed_forw
|
||||||
|
result.forward_mode = mode.river_down
|
||||||
|
result.backward_mode = mode.river_up
|
||||||
|
speed_forw = temp_speed*1.5
|
||||||
|
speed_back = temp_speed/1.5
|
||||||
|
elseif highway == "steps" then
|
||||||
|
result.forward_mode = mode.steps_down
|
||||||
|
result.backward_mode = mode.steps_up
|
||||||
|
end
|
||||||
|
|
||||||
|
if maxspeed_forward ~= nil and maxspeed_forward > 0 then
|
||||||
|
speed_forw = maxspeed_forward
|
||||||
|
else
|
||||||
|
if maxspeed ~= nil and maxspeed > 0 and speed_forw > maxspeed then
|
||||||
|
speed_forw = maxspeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if maxspeed_backward ~= nil and maxspeed_backward > 0 then
|
||||||
|
speed_back = maxspeed_backward
|
||||||
|
else
|
||||||
|
if maxspeed ~=nil and maxspeed > 0 and speed_back > maxspeed then
|
||||||
|
speed_back = maxspeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result.forward_speed = speed_forw
|
||||||
|
result.backward_speed = speed_back
|
||||||
|
end
|
||||||
|
|
||||||
|
if oneway == "no" or oneway == "0" or oneway == "false" then
|
||||||
|
-- nothing to do
|
||||||
|
elseif oneway == "-1" then
|
||||||
|
result.forward_mode = mode.inaccessible
|
||||||
|
elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" then
|
||||||
|
result.backward_mode = mode.inaccessible
|
||||||
|
end
|
||||||
|
|
||||||
|
if highway == 'motorway' then
|
||||||
|
result.forward_classes["motorway"] = true
|
||||||
|
result.backward_classes["motorway"] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if toll == "yes" then
|
||||||
|
result.forward_classes["toll"] = true
|
||||||
|
result.backward_classes["toll"] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if junction == 'roundabout' then
|
||||||
|
result.roundabout = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_turn (profile, turn)
|
||||||
|
if (2 < nil) then
|
||||||
|
print("2 is less than nil")
|
||||||
|
end
|
||||||
|
|
||||||
|
if turn.is_u_turn then
|
||||||
|
turn.duration = turn.duration + profile.properties.u_turn_penalty
|
||||||
|
turn.weight = turn.weight + profile.properties.u_turn_penalty
|
||||||
|
end
|
||||||
|
if turn.has_traffic_light then
|
||||||
|
turn.duration = turn.duration + profile.properties.traffic_light_penalty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
setup = setup,
|
||||||
|
process_way = process_way,
|
||||||
|
process_node = process_node,
|
||||||
|
process_turn = process_turn
|
||||||
|
}
|
140
test/data/profiles/bad_way.lua
Normal file
140
test/data/profiles/bad_way.lua
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
-- copy of testbot with process_way throwing a runtime error
|
||||||
|
|
||||||
|
api_version = 4
|
||||||
|
|
||||||
|
function setup()
|
||||||
|
return {
|
||||||
|
properties = {
|
||||||
|
continue_straight_at_waypoint = true,
|
||||||
|
max_speed_for_map_matching = 30/3.6, --km -> m/s
|
||||||
|
weight_name = 'duration',
|
||||||
|
process_call_tagless_node = false,
|
||||||
|
u_turn_penalty = 20,
|
||||||
|
traffic_light_penalty = 7, -- seconds
|
||||||
|
use_turn_restrictions = true
|
||||||
|
},
|
||||||
|
|
||||||
|
classes = {"motorway", "toll", "TooWords2"},
|
||||||
|
|
||||||
|
excludable = {
|
||||||
|
{["motorway"] = true},
|
||||||
|
{["toll"] = true},
|
||||||
|
{["motorway"] = true, ["toll"] = true}
|
||||||
|
},
|
||||||
|
|
||||||
|
default_speed = 24,
|
||||||
|
speeds = {
|
||||||
|
primary = 36,
|
||||||
|
secondary = 18,
|
||||||
|
tertiary = 12,
|
||||||
|
steps = 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_node (profile, node, result)
|
||||||
|
-- check if node is a traffic light
|
||||||
|
-- TODO: a way to set the penalty value
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_way (profile, way, result)
|
||||||
|
if (2 < nil) then
|
||||||
|
print("2 less than nil")
|
||||||
|
end
|
||||||
|
|
||||||
|
local highway = way:get_value_by_key("highway")
|
||||||
|
local toll = way:get_value_by_key("toll")
|
||||||
|
local name = way:get_value_by_key("name")
|
||||||
|
local oneway = way:get_value_by_key("oneway")
|
||||||
|
local route = way:get_value_by_key("route")
|
||||||
|
local duration = way:get_value_by_key("duration")
|
||||||
|
local maxspeed = tonumber(way:get_value_by_key ( "maxspeed"))
|
||||||
|
local maxspeed_forward = tonumber(way:get_value_by_key( "maxspeed:forward"))
|
||||||
|
local maxspeed_backward = tonumber(way:get_value_by_key( "maxspeed:backward"))
|
||||||
|
local junction = way:get_value_by_key("junction")
|
||||||
|
|
||||||
|
if name then
|
||||||
|
result.name = name
|
||||||
|
end
|
||||||
|
|
||||||
|
result.forward_mode = mode.driving
|
||||||
|
result.backward_mode = mode.driving
|
||||||
|
|
||||||
|
if duration and durationIsValid(duration) then
|
||||||
|
result.duration = math.max( 1, parseDuration(duration) )
|
||||||
|
result.forward_mode = mode.route
|
||||||
|
result.backward_mode = mode.route
|
||||||
|
else
|
||||||
|
local speed_forw = profile.speeds[highway] or profile.default_speed
|
||||||
|
local speed_back = speed_forw
|
||||||
|
|
||||||
|
if highway == "river" then
|
||||||
|
local temp_speed = speed_forw
|
||||||
|
result.forward_mode = mode.river_down
|
||||||
|
result.backward_mode = mode.river_up
|
||||||
|
speed_forw = temp_speed*1.5
|
||||||
|
speed_back = temp_speed/1.5
|
||||||
|
elseif highway == "steps" then
|
||||||
|
result.forward_mode = mode.steps_down
|
||||||
|
result.backward_mode = mode.steps_up
|
||||||
|
end
|
||||||
|
|
||||||
|
if maxspeed_forward ~= nil and maxspeed_forward > 0 then
|
||||||
|
speed_forw = maxspeed_forward
|
||||||
|
else
|
||||||
|
if maxspeed ~= nil and maxspeed > 0 and speed_forw > maxspeed then
|
||||||
|
speed_forw = maxspeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if maxspeed_backward ~= nil and maxspeed_backward > 0 then
|
||||||
|
speed_back = maxspeed_backward
|
||||||
|
else
|
||||||
|
if maxspeed ~=nil and maxspeed > 0 and speed_back > maxspeed then
|
||||||
|
speed_back = maxspeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result.forward_speed = speed_forw
|
||||||
|
result.backward_speed = speed_back
|
||||||
|
end
|
||||||
|
|
||||||
|
if oneway == "no" or oneway == "0" or oneway == "false" then
|
||||||
|
-- nothing to do
|
||||||
|
elseif oneway == "-1" then
|
||||||
|
result.forward_mode = mode.inaccessible
|
||||||
|
elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" then
|
||||||
|
result.backward_mode = mode.inaccessible
|
||||||
|
end
|
||||||
|
|
||||||
|
if highway == 'motorway' then
|
||||||
|
result.forward_classes["motorway"] = true
|
||||||
|
result.backward_classes["motorway"] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if toll == "yes" then
|
||||||
|
result.forward_classes["toll"] = true
|
||||||
|
result.backward_classes["toll"] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if junction == 'roundabout' then
|
||||||
|
result.roundabout = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_turn (profile, turn)
|
||||||
|
if turn.is_u_turn then
|
||||||
|
turn.duration = turn.duration + profile.properties.u_turn_penalty
|
||||||
|
turn.weight = turn.weight + profile.properties.u_turn_penalty
|
||||||
|
end
|
||||||
|
if turn.has_traffic_light then
|
||||||
|
turn.duration = turn.duration + profile.properties.traffic_light_penalty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
setup = setup,
|
||||||
|
process_way = process_way,
|
||||||
|
process_node = process_node,
|
||||||
|
process_turn = process_turn
|
||||||
|
}
|
@ -112,6 +112,18 @@ test('constructor: throws if dataset_name is not a string', function(assert) {
|
|||||||
assert.throws(function() { new OSRM({dataset_name: "unsued_name___", shared_memory: true}); }, /Could not find shared memory region/, 'Does not accept wrong name');
|
assert.throws(function() { new OSRM({dataset_name: "unsued_name___", shared_memory: true}); }, /Could not find shared memory region/, 'Does not accept wrong name');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('constructor: takes a default_radius argument', function(assert) {
|
||||||
|
assert.plan(1);
|
||||||
|
var osrm = new OSRM({algorithm: 'MLD', path: monaco_mld_path, default_radius: 1});
|
||||||
|
assert.ok(osrm);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('constructor: throws if default_radius is not a number', function(assert) {
|
||||||
|
assert.plan(2);
|
||||||
|
assert.throws(function() { new OSRM({algorithm: 'MLD', path: monaco_mld_path, default_radius: 'abc'}); }, /default_radius must be an integral number/, 'Does not accept string');
|
||||||
|
assert.ok(new OSRM({algorithm: 'MLD', path: monaco_mld_path, default_radius: 1}), 'Does accept number');
|
||||||
|
});
|
||||||
|
|
||||||
test('constructor: parses custom limits', function(assert) {
|
test('constructor: parses custom limits', function(assert) {
|
||||||
assert.plan(1);
|
assert.plan(1);
|
||||||
var osrm = new OSRM({
|
var osrm = new OSRM({
|
||||||
|
@ -1,10 +1,32 @@
|
|||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include "osrm/exception.hpp"
|
||||||
#include "osrm/extractor.hpp"
|
#include "osrm/extractor.hpp"
|
||||||
#include "osrm/extractor_config.hpp"
|
#include "osrm/extractor_config.hpp"
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
// utility class to redirect stderr so we can test it
|
||||||
|
// inspired by https://stackoverflow.com/questions/5405016
|
||||||
|
class redirect_stderr
|
||||||
|
{
|
||||||
|
// constructor: accept a pointer to a buffer where stderr will be redirected
|
||||||
|
public:
|
||||||
|
redirect_stderr(std::streambuf *buf)
|
||||||
|
// store the original buffer for later (original buffer returned by rdbuf)
|
||||||
|
: old(std::cerr.rdbuf(buf))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor: restore the original cerr, regardless of how this class gets destroyed
|
||||||
|
~redirect_stderr() { std::cerr.rdbuf(old); }
|
||||||
|
|
||||||
|
// place to store the buffer
|
||||||
|
private:
|
||||||
|
std::streambuf *old;
|
||||||
|
};
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(library_extract)
|
BOOST_AUTO_TEST_SUITE(library_extract)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_extract_with_invalid_config)
|
BOOST_AUTO_TEST_CASE(test_extract_with_invalid_config)
|
||||||
@ -26,4 +48,114 @@ BOOST_AUTO_TEST_CASE(test_extract_with_valid_config)
|
|||||||
BOOST_CHECK_NO_THROW(osrm::extract(config));
|
BOOST_CHECK_NO_THROW(osrm::extract(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_setup_runtime_error)
|
||||||
|
{
|
||||||
|
osrm::ExtractorConfig config;
|
||||||
|
config.input_path = OSRM_TEST_DATA_DIR "/monaco.osm.pbf";
|
||||||
|
config.UseDefaultOutputNames(OSRM_TEST_DATA_DIR "/monaco.osm.pbf");
|
||||||
|
config.profile_path = OSRM_TEST_DATA_DIR "/profiles/bad_setup.lua";
|
||||||
|
config.small_component_size = 1000;
|
||||||
|
config.requested_num_threads = std::thread::hardware_concurrency();
|
||||||
|
|
||||||
|
std::stringstream output;
|
||||||
|
|
||||||
|
{
|
||||||
|
redirect_stderr redir(output.rdbuf());
|
||||||
|
BOOST_CHECK_THROW(osrm::extract(config), osrm::util::exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We just look for the line number, file name, and error message. This avoids portability
|
||||||
|
// issues since the output contains the full path to the file, which may change between systems
|
||||||
|
BOOST_CHECK(boost::algorithm::contains(output.str(),
|
||||||
|
"bad_setup.lua:6: attempt to compare number with nil"));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_way_runtime_error)
|
||||||
|
{
|
||||||
|
osrm::ExtractorConfig config;
|
||||||
|
config.input_path = OSRM_TEST_DATA_DIR "/monaco.osm.pbf";
|
||||||
|
config.UseDefaultOutputNames(OSRM_TEST_DATA_DIR "/monaco.osm.pbf");
|
||||||
|
config.profile_path = OSRM_TEST_DATA_DIR "/profiles/bad_way.lua";
|
||||||
|
config.small_component_size = 1000;
|
||||||
|
config.requested_num_threads = std::thread::hardware_concurrency();
|
||||||
|
|
||||||
|
std::stringstream output;
|
||||||
|
|
||||||
|
{
|
||||||
|
redirect_stderr redir(output.rdbuf());
|
||||||
|
BOOST_CHECK_THROW(osrm::extract(config), osrm::util::exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We just look for the line number, file name, and error message. This avoids portability
|
||||||
|
// issues since the output contains the full path to the file, which may change between systems
|
||||||
|
BOOST_CHECK(boost::algorithm::contains(output.str(),
|
||||||
|
"bad_way.lua:41: attempt to compare number with nil"));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_node_runtime_error)
|
||||||
|
{
|
||||||
|
osrm::ExtractorConfig config;
|
||||||
|
config.input_path = OSRM_TEST_DATA_DIR "/monaco.osm.pbf";
|
||||||
|
config.UseDefaultOutputNames(OSRM_TEST_DATA_DIR "/monaco.osm.pbf");
|
||||||
|
config.profile_path = OSRM_TEST_DATA_DIR "/profiles/bad_node.lua";
|
||||||
|
config.small_component_size = 1000;
|
||||||
|
config.requested_num_threads = std::thread::hardware_concurrency();
|
||||||
|
|
||||||
|
std::stringstream output;
|
||||||
|
|
||||||
|
{
|
||||||
|
redirect_stderr redir(output.rdbuf());
|
||||||
|
BOOST_CHECK_THROW(osrm::extract(config), osrm::util::exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We just look for the line number, file name, and error message. This avoids portability
|
||||||
|
// issues since the output contains the full path to the file, which may change between systems
|
||||||
|
BOOST_CHECK(boost::algorithm::contains(output.str(),
|
||||||
|
"bad_node.lua:36: attempt to compare number with nil"));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_segment_runtime_error)
|
||||||
|
{
|
||||||
|
osrm::ExtractorConfig config;
|
||||||
|
config.input_path = OSRM_TEST_DATA_DIR "/monaco.osm.pbf";
|
||||||
|
config.UseDefaultOutputNames(OSRM_TEST_DATA_DIR "/monaco.osm.pbf");
|
||||||
|
config.profile_path = OSRM_TEST_DATA_DIR "/profiles/bad_segment.lua";
|
||||||
|
config.small_component_size = 1000;
|
||||||
|
config.requested_num_threads = std::thread::hardware_concurrency();
|
||||||
|
|
||||||
|
std::stringstream output;
|
||||||
|
|
||||||
|
{
|
||||||
|
redirect_stderr redir(output.rdbuf());
|
||||||
|
BOOST_CHECK_THROW(osrm::extract(config), osrm::util::exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We just look for the line number, file name, and error message. This avoids portability
|
||||||
|
// issues since the output contains the full path to the file, which may change between systems
|
||||||
|
BOOST_CHECK(boost::algorithm::contains(
|
||||||
|
output.str(), "bad_segment.lua:132: attempt to compare number with nil"));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_turn_runtime_error)
|
||||||
|
{
|
||||||
|
osrm::ExtractorConfig config;
|
||||||
|
config.input_path = OSRM_TEST_DATA_DIR "/monaco.osm.pbf";
|
||||||
|
config.UseDefaultOutputNames(OSRM_TEST_DATA_DIR "/monaco.osm.pbf");
|
||||||
|
config.profile_path = OSRM_TEST_DATA_DIR "/profiles/bad_turn.lua";
|
||||||
|
config.small_component_size = 1000;
|
||||||
|
config.requested_num_threads = std::thread::hardware_concurrency();
|
||||||
|
|
||||||
|
std::stringstream output;
|
||||||
|
|
||||||
|
{
|
||||||
|
redirect_stderr redir(output.rdbuf());
|
||||||
|
BOOST_CHECK_THROW(osrm::extract(config), osrm::util::exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We just look for the line number, file name, and error message. This avoids portability
|
||||||
|
// issues since the output contains the full path to the file, which may change between systems
|
||||||
|
BOOST_CHECK(boost::algorithm::contains(output.str(),
|
||||||
|
"bad_turn.lua:122: attempt to compare number with nil"));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
Loading…
Reference in New Issue
Block a user