diff --git a/CHANGELOG.md b/CHANGELOG.md index adbe9dcc43..fba618e7bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ * FIXED: Aggregation updates: update opposing local idx after aggregating the edges, added classification check for aggregation, and shortcut length changes [#4570](https://github.com/valhalla/valhalla/pull/4570) * FIXED: Use helper function for only parsing out names from DirectedEdge when populating intersecting edges [#4604](https://github.com/valhalla/valhalla/pull/4604) * FIXED: Osmnode size reduction: Fixed excessive disk space for planet build [#4605](https://github.com/valhalla/valhalla/pull/4605) + * FIXED: Conflict with signinfo's temporary linguistic node sequence file caused test failures. [#4625](https://github.com/valhalla/valhalla/pull/4625) * FIXED: CostMatrix for trivial routes with oneways [#4626](https://github.com/valhalla/valhalla/pull/4626) * FIXED: some entry points to creating geotiff isochrones output did not register the geotiff driver before attempting to use it [#4628](https://github.com/valhalla/valhalla/pull/4628) * **Enhancement** @@ -98,7 +99,7 @@ * FIXED: Fixed roundoff issue in Tiles Row and Col methods [#4585](https://github.com/valhalla/valhalla/pull/4585) * ADDED: isochrone proper polygon support & pbf output for isochrone [#4575](https://github.com/valhalla/valhalla/pull/4575) * ADDED: return isotile grid as geotiff [#4594](https://github.com/valhalla/valhalla/pull/4594) - * FIXED: Conflict with signinfo's temporary linguistic node sequence file caused test failures. [#4625](https://github.com/valhalla/valhalla/pull/4625) + * ADDED: `ignore_non_vehicular_restrictions` parameter for truck costing [#4606](https://github.com/valhalla/valhalla/pull/4606) ## Release Date: 2023-05-11 Valhalla 3.4.0 * **Removed** diff --git a/docs/docs/api/turn-by-turn/api-reference.md b/docs/docs/api/turn-by-turn/api-reference.md index 1ee45e701e..1676f3895c 100644 --- a/docs/docs/api/turn-by-turn/api-reference.md +++ b/docs/docs/api/turn-by-turn/api-reference.md @@ -121,6 +121,10 @@ These options are available for `auto`, `bus`, and `truck` costing methods. | `fixed_speed` | Fixed speed the vehicle can go. Used to override the calculated speed. Can be useful if speed of vehicle is known. `fixed_speed` must be between 1 and 252 KPH. The default value is 0 KPH which disables fixed speed and falls back to the standard calculated speed based on the road attribution. | | `ignore_closures` | If set to `true`, ignores all closures, marked due to live traffic closures, during routing. **Note:** This option cannot be set if `location.search_filter.exclude_closures` is also specified in the request and will return an error if it is | | `closure_factor` | A factor that penalizes the cost when traversing a closed edge (eg: if `search_filter.exclude_closures` is `false` for origin and/or destination location and the route starts/ends on closed edges). Its value can range from `1.0` - don't penalize closed edges, to `10.0` - apply high cost penalty to closed edges. Default value is `9.0`. **Note:** This factor is applicable only for motorized modes of transport, i.e `auto`, `motorcycle`, `motor_scooter`, `bus`, `truck` & `taxi`. | +| `ignore_restrictions` | If set to `true`, ignores any restrictions (e.g. turn/dimensional/conditional restrictions). Especially useful for matching GPS traces to the road network regardless of restrictions. Default is `false`. | +| `ignore_non_vehicular_restrictions` | Similar to `ignore_restrictions`, but will respect restrictions that impact vehicle safety, such as weight and size restrictions. | +| `ignore_access` | Will ignore mode-specific access tags. Especially useful for matching GPS traces to the road network regardless of restrictions. Default is `false`. | +| `ignore_closures` | Will ignore traffic closures. Default is `false`. | ###### Other costing options The following options are available for `auto`, `bus`, `taxi`, and `truck` costing methods. diff --git a/proto/options.proto b/proto/options.proto index 122db3b360..79549f216a 100644 --- a/proto/options.proto +++ b/proto/options.proto @@ -312,6 +312,7 @@ message Costing { uint32 axle_count = 81; float use_lit = 82; bool disable_hierarchy_pruning = 83; + bool ignore_non_vehicular_restrictions = 84; } oneof has_options { diff --git a/src/sif/autocost.cc b/src/sif/autocost.cc index 34662ab292..93a3dbd648 100644 --- a/src/sif/autocost.cc +++ b/src/sif/autocost.cc @@ -421,7 +421,7 @@ bool AutoCost::Allowed(const baldr::DirectedEdge* edge, // a not thru region and a heading selected an edge entering the // region. if (!IsAccessible(edge) || (!pred.deadend() && pred.opp_local_idx() == edge->localedgeidx()) || - ((pred.restrictions() & (1 << edge->localedgeidx())) && !ignore_restrictions_) || + ((pred.restrictions() & (1 << edge->localedgeidx())) && !ignore_turn_restrictions_) || edge->surface() == Surface::kImpassable || IsUserAvoidEdge(edgeid) || (!allow_destination_only_ && !pred.destonly() && edge->destonly()) || (pred.closure_pruning() && IsClosed(edge, tile)) || @@ -446,7 +446,7 @@ bool AutoCost::AllowedReverse(const baldr::DirectedEdge* edge, // Check access, U-turn, and simple turn restriction. // Allow U-turns at dead-end nodes. if (!IsAccessible(opp_edge) || (!pred.deadend() && pred.opp_local_idx() == edge->localedgeidx()) || - ((opp_edge->restrictions() & (1 << pred.opp_local_idx())) && !ignore_restrictions_) || + ((opp_edge->restrictions() & (1 << pred.opp_local_idx())) && !ignore_turn_restrictions_) || opp_edge->surface() == Surface::kImpassable || IsUserAvoidEdge(opp_edgeid) || (!allow_destination_only_ && !pred.destonly() && opp_edge->destonly()) || (pred.closure_pruning() && IsClosed(opp_edge, tile)) || @@ -808,7 +808,7 @@ bool BusCost::AllowedReverse(const baldr::DirectedEdge* edge, // Check access, U-turn, and simple turn restriction. // Allow U-turns at dead-end nodes. if (!IsAccessible(opp_edge) || (!pred.deadend() && pred.opp_local_idx() == edge->localedgeidx()) || - ((opp_edge->restrictions() & (1 << pred.opp_local_idx())) && !ignore_restrictions_) || + ((opp_edge->restrictions() & (1 << pred.opp_local_idx())) && !ignore_turn_restrictions_) || opp_edge->surface() == Surface::kImpassable || IsUserAvoidEdge(opp_edgeid) || (!allow_destination_only_ && !pred.destonly() && opp_edge->destonly()) || (pred.closure_pruning() && IsClosed(opp_edge, tile)) || @@ -987,7 +987,7 @@ bool TaxiCost::AllowedReverse(const baldr::DirectedEdge* edge, // Check access, U-turn, and simple turn restriction. // Allow U-turns at dead-end nodes. if (!IsAccessible(opp_edge) || (!pred.deadend() && pred.opp_local_idx() == edge->localedgeidx()) || - ((opp_edge->restrictions() & (1 << pred.opp_local_idx())) && !ignore_restrictions_) || + ((opp_edge->restrictions() & (1 << pred.opp_local_idx())) && !ignore_turn_restrictions_) || opp_edge->surface() == Surface::kImpassable || IsUserAvoidEdge(opp_edgeid) || (!allow_destination_only_ && !pred.destonly() && opp_edge->destonly()) || (pred.closure_pruning() && IsClosed(opp_edge, tile)) || diff --git a/src/sif/bicyclecost.cc b/src/sif/bicyclecost.cc index 887b312d87..46a07b54d6 100644 --- a/src/sif/bicyclecost.cc +++ b/src/sif/bicyclecost.cc @@ -545,7 +545,7 @@ bool BicycleCost::Allowed(const baldr::DirectedEdge* edge, if (!IsAccessible(edge) || edge->is_shortcut() || (!pred.deadend() && pred.opp_local_idx() == edge->localedgeidx() && pred.mode() == TravelMode::kBicycle) || - (!ignore_restrictions_ && (pred.restrictions() & (1 << edge->localedgeidx()))) || + (!ignore_turn_restrictions_ && (pred.restrictions() & (1 << edge->localedgeidx()))) || IsUserAvoidEdge(edgeid)) { return false; } @@ -582,7 +582,7 @@ bool BicycleCost::AllowedReverse(const baldr::DirectedEdge* edge, opp_edge->use() == Use::kPlatformConnection || (!pred.deadend() && pred.opp_local_idx() == edge->localedgeidx() && pred.mode() == TravelMode::kBicycle) || - (!ignore_restrictions_ && (opp_edge->restrictions() & (1 << pred.opp_local_idx()))) || + (!ignore_turn_restrictions_ && (opp_edge->restrictions() & (1 << pred.opp_local_idx()))) || IsUserAvoidEdge(opp_edgeid)) { return false; } diff --git a/src/sif/dynamiccost.cc b/src/sif/dynamiccost.cc index 5416fb7de9..c92ec6e33a 100644 --- a/src/sif/dynamiccost.cc +++ b/src/sif/dynamiccost.cc @@ -151,6 +151,9 @@ DynamicCost::DynamicCost(const Costing& costing, closure_factor_(kDefaultClosureFactor), flow_mask_(kDefaultFlowMask), shortest_(costing.options().shortest()), ignore_restrictions_(costing.options().ignore_restrictions()), + ignore_non_vehicular_restrictions_(costing.options().ignore_non_vehicular_restrictions()), + ignore_turn_restrictions_(costing.options().ignore_restrictions() || + costing.options().ignore_non_vehicular_restrictions()), ignore_oneways_(costing.options().ignore_oneways()), ignore_access_(costing.options().ignore_access()), ignore_closures_(costing.options().ignore_closures()), @@ -389,6 +392,8 @@ void ParseBaseCostOptions(const rapidjson::Value& json, JSON_PBF_DEFAULT(co, false, json, "/ignore_oneways", ignore_oneways); JSON_PBF_DEFAULT(co, false, json, "/ignore_access", ignore_access); JSON_PBF_DEFAULT(co, false, json, "/ignore_closures", ignore_closures); + JSON_PBF_DEFAULT_V2(co, false, json, "/ignore_non_vehicular_restrictions", + ignore_non_vehicular_restrictions); // shortest JSON_PBF_DEFAULT(co, false, json, "/shortest", shortest); diff --git a/src/sif/motorcyclecost.cc b/src/sif/motorcyclecost.cc index 43388c91d3..1f716bd499 100644 --- a/src/sif/motorcyclecost.cc +++ b/src/sif/motorcyclecost.cc @@ -355,7 +355,7 @@ bool MotorcycleCost::Allowed(const baldr::DirectedEdge* edge, // Check access, U-turn, and simple turn restriction. // Allow U-turns at dead-end nodes. if (!IsAccessible(edge) || (!pred.deadend() && pred.opp_local_idx() == edge->localedgeidx()) || - ((pred.restrictions() & (1 << edge->localedgeidx())) && !ignore_restrictions_) || + ((pred.restrictions() & (1 << edge->localedgeidx())) && !ignore_turn_restrictions_) || (edge->surface() > kMinimumMotorcycleSurface) || IsUserAvoidEdge(edgeid) || (!allow_destination_only_ && !pred.destonly() && edge->destonly()) || (pred.closure_pruning() && IsClosed(edge, tile))) { @@ -379,7 +379,7 @@ bool MotorcycleCost::AllowedReverse(const baldr::DirectedEdge* edge, // Check access, U-turn, and simple turn restriction. // Allow U-turns at dead-end nodes. if (!IsAccessible(opp_edge) || (!pred.deadend() && pred.opp_local_idx() == edge->localedgeidx()) || - ((opp_edge->restrictions() & (1 << pred.opp_local_idx())) && !ignore_restrictions_) || + ((opp_edge->restrictions() & (1 << pred.opp_local_idx())) && !ignore_turn_restrictions_) || (opp_edge->surface() > kMinimumMotorcycleSurface) || IsUserAvoidEdge(opp_edgeid) || (!allow_destination_only_ && !pred.destonly() && opp_edge->destonly()) || (pred.closure_pruning() && IsClosed(opp_edge, tile))) { diff --git a/src/sif/motorscootercost.cc b/src/sif/motorscootercost.cc index 2ac26e8c13..7fe8270f05 100644 --- a/src/sif/motorscootercost.cc +++ b/src/sif/motorscootercost.cc @@ -376,7 +376,7 @@ bool MotorScooterCost::Allowed(const baldr::DirectedEdge* edge, // Check access, U-turn, and simple turn restriction. // Allow U-turns at dead-end nodes. if (!IsAccessible(edge) || (!pred.deadend() && pred.opp_local_idx() == edge->localedgeidx()) || - ((pred.restrictions() & (1 << edge->localedgeidx())) && !ignore_restrictions_) || + ((pred.restrictions() & (1 << edge->localedgeidx())) && !ignore_turn_restrictions_) || (edge->surface() > kMinimumScooterSurface) || IsUserAvoidEdge(edgeid) || (!allow_destination_only_ && !pred.destonly() && edge->destonly()) || (pred.closure_pruning() && IsClosed(edge, tile))) { @@ -400,7 +400,7 @@ bool MotorScooterCost::AllowedReverse(const baldr::DirectedEdge* edge, // Check access, U-turn, and simple turn restriction. // Allow U-turns at dead-end nodes. if (!IsAccessible(opp_edge) || (!pred.deadend() && pred.opp_local_idx() == edge->localedgeidx()) || - ((opp_edge->restrictions() & (1 << pred.opp_local_idx())) && !ignore_restrictions_) || + ((opp_edge->restrictions() & (1 << pred.opp_local_idx())) && !ignore_turn_restrictions_) || (opp_edge->surface() > kMinimumScooterSurface) || IsUserAvoidEdge(opp_edgeid) || (!allow_destination_only_ && !pred.destonly() && opp_edge->destonly()) || (pred.closure_pruning() && IsClosed(opp_edge, tile))) { diff --git a/src/sif/truckcost.cc b/src/sif/truckcost.cc index 52eec75ab2..94b8b4ba42 100644 --- a/src/sif/truckcost.cc +++ b/src/sif/truckcost.cc @@ -439,7 +439,7 @@ inline bool TruckCost::Allowed(const baldr::DirectedEdge* edge, uint8_t& restriction_idx) const { // Check access, U-turn, and simple turn restriction. if (!IsAccessible(edge) || (!pred.deadend() && pred.opp_local_idx() == edge->localedgeidx()) || - ((pred.restrictions() & (1 << edge->localedgeidx())) && !ignore_restrictions_) || + ((pred.restrictions() & (1 << edge->localedgeidx())) && (!ignore_turn_restrictions_)) || edge->surface() == Surface::kImpassable || IsUserAvoidEdge(edgeid) || (!allow_destination_only_ && !pred.destonly() && edge->destonly_hgv()) || (pred.closure_pruning() && IsClosed(edge, tile)) || @@ -463,7 +463,7 @@ bool TruckCost::AllowedReverse(const baldr::DirectedEdge* edge, uint8_t& restriction_idx) const { // Check access, U-turn, and simple turn restriction. if (!IsAccessible(opp_edge) || (!pred.deadend() && pred.opp_local_idx() == edge->localedgeidx()) || - ((opp_edge->restrictions() & (1 << pred.opp_local_idx())) && !ignore_restrictions_) || + ((opp_edge->restrictions() & (1 << pred.opp_local_idx())) && !ignore_turn_restrictions_) || opp_edge->surface() == Surface::kImpassable || IsUserAvoidEdge(opp_edgeid) || (!allow_destination_only_ && !pred.destonly() && opp_edge->destonly_hgv()) || (pred.closure_pruning() && IsClosed(opp_edge, tile)) || diff --git a/test/gurka/test_closure_penalty.cc b/test/gurka/test_closure_penalty.cc index a98a78e082..437a84b4f9 100644 --- a/test/gurka/test_closure_penalty.cc +++ b/test/gurka/test_closure_penalty.cc @@ -1,3 +1,5 @@ +#include + #include "gurka.h" #include "test.h" diff --git a/test/gurka/test_conditional_restrictions.cc b/test/gurka/test_conditional_restrictions.cc index d161168d6b..390c3a48d1 100644 --- a/test/gurka/test_conditional_restrictions.cc +++ b/test/gurka/test_conditional_restrictions.cc @@ -97,8 +97,9 @@ class ConditionalRestrictions : public ::testing::Test { }; const auto layout = gurka::detail::map_to_coordinates(ascii_map, grid_size_meters); - map = gurka::buildtiles(layout, ways, {}, {}, "test/data/conditional_restrictions", - {{"mjolnir.timezone", {"test/data/tz.sqlite"}}}); + map = gurka::buildtiles(layout, ways, {}, {}, + VALHALLA_BUILD_DIR "test/data/conditional_restrictions", + {{"mjolnir.timezone", {VALHALLA_BUILD_DIR "test/data/tz.sqlite"}}}); } }; diff --git a/test/gurka/test_ignore_restrictions.cc b/test/gurka/test_ignore_restrictions.cc new file mode 100644 index 0000000000..6ccf458cba --- /dev/null +++ b/test/gurka/test_ignore_restrictions.cc @@ -0,0 +1,180 @@ + +#include "gurka.h" +#include "test.h" +#include + +using namespace valhalla; + +std::string get_access_mode(const std::string& costing_mode) { + if (costing_mode == "auto") { + return "motorcar"; + } else if (costing_mode == "truck") { + return "hgv"; + } else if (costing_mode == "motorcycle") { + return "motorcycle"; + } else if (costing_mode == "taxi") { + return "taxi"; + } else if (costing_mode == "bus") { + return "bus"; + } else if (costing_mode == "motor_scooter") { + return "moped"; + } else if (costing_mode == "bicycle") { + return "bicycle"; + } + + throw std::runtime_error("unexpected costing mode " + costing_mode + "."); +} + +class CommonRestrictionTest : public ::testing::TestWithParam { +protected: + static gurka::nodelayout layout; + + static void SetUpTestSuite() { + constexpr double gridsize = 500; + + const std::string map = R"( + A----------B-----C----D + | + E + | + | + F + )"; + + layout = gurka::detail::map_to_coordinates(map, gridsize); + } +}; +gurka::nodelayout CommonRestrictionTest::layout = {}; + +TEST_P(CommonRestrictionTest, IgnoreCommonRestrictions) { + const std::string& costing = GetParam(); + const gurka::ways ways = { + {"AB", {{"highway", "secondary"}}}, + {"BC", {{"highway", "secondary"}}}, + {"CD", {{"highway", "secondary"}}}, + {"AE", {{"highway", "secondary"}}}, + {"EF", + {{"highway", "secondary"}, {get_access_mode(costing) + ":conditional", "no @ (09:00-18:00)"}}}, + }; + const gurka::relations relations = {{{ + {gurka::way_member, "AB", "from"}, + {gurka::way_member, "BC", "to"}, + {gurka::node_member, "B", "via"}, + }, + {{"type", "restriction"}, {"restriction", "no_straight_on"}}}}; + gurka::map map = + gurka::buildtiles(layout, ways, {}, relations, "test/data/ignore_non_vehicular_restrictions", + {{"mjolnir.timezone", {VALHALLA_BUILD_DIR "test/data/tz.sqlite"}}}); + // first, route through turn restriction, should fail... + try { + valhalla::Api route = gurka::do_action(valhalla::Options::route, map, {"A", "D"}, costing, {}); + FAIL() << "Expected valhalla_exception_t."; + } catch (const valhalla_exception_t& err) { EXPECT_EQ(err.code, 442); } catch (...) { + FAIL() << "Expected valhalla_exception_t."; + } + + // ...but succeed with ignore_non_vehicular_restrictions + valhalla::Api route = + gurka::do_action(valhalla::Options::route, map, {"A", "D"}, costing, + {{"/costing_options/" + costing + "/ignore_non_vehicular_restrictions", "1"}}); + gurka::assert::raw::expect_path(route, {"AB", "BC", "CD"}); + + // second, route through time based access restrictions, should fail... + try { + valhalla::Api route = + gurka::do_action(valhalla::Options::route, map, {"A", "F"}, costing, + {{"/date_time/type", "1"}, {"/date_time/value", "2020-10-10T13:00"}}); + FAIL() << "Expected route to fail."; + } catch (const valhalla_exception_t& err) { EXPECT_EQ(err.code, 442); } catch (...) { + FAIL() << "Expected different error code."; + } + + //...but succeed with ignore_non_vehicular_restrictions + valhalla::Api route_succeed = + gurka::do_action(valhalla::Options::route, map, {"A", "F"}, costing, + {{"/costing_options/" + costing + "/ignore_non_vehicular_restrictions", "1"}, + {"/date_time/type", "1"}, + {"/date_time/value", "2020-10-10T13:00"}}); + gurka::assert::raw::expect_path(route_succeed, {"AE", "EF"}); +} + +// check that dimensional restrictions are not affected +TEST_P(CommonRestrictionTest, IgnoreCommonRestrictionsFail) { + const std::string& costing = GetParam(); + + if (costing == "motorcycle" || costing == "bicycle" || costing == "motor_scooter") + return; // no height restrictions for these + + const gurka::ways ways = { + {"AB", {{"highway", "secondary"}}}, {"BC", {{"highway", "secondary"}, {"maxheight", "2.5"}}}, + {"CD", {{"highway", "secondary"}}}, {"AE", {{"highway", "secondary"}}}, + {"EF", {{"highway", "secondary"}}}, + }; + gurka::map map = + gurka::buildtiles(layout, ways, {}, {}, "test/data/ignore_non_vehicular_restrictions", + {{"mjolnir.timezone", {VALHALLA_BUILD_DIR "test/data/tz.sqlite"}}}); + // should fail, too low + try { + valhalla::Api route = gurka::do_action(valhalla::Options::route, map, {"A", "D"}, costing, + {{"/costing_options/" + costing + "/height", "3"}}); + FAIL() << "Expected valhalla_exception_t."; + } catch (const valhalla_exception_t& err) { EXPECT_EQ(err.code, 442); } catch (...) { + FAIL() << "Expected valhalla_exception_t."; + } + + // still too low + try { + valhalla::Api route = + gurka::do_action(valhalla::Options::route, map, {"A", "D"}, costing, + {{"/costing_options/" + costing + "/ignore_non_vehicular_restrictions", "1"}, + {"/costing_options/" + costing + "/height", "3"}}); + FAIL() << "Expected valhalla_exception_t."; + } catch (const valhalla_exception_t& err) { EXPECT_EQ(err.code, 442); } catch (...) { + FAIL() << "Expected valhalla_exception_t."; + } +} +INSTANTIATE_TEST_SUITE_P( + CommonRestrictionsTest, + CommonRestrictionTest, + ::testing::Values("auto", "truck", "motorcycle", "taxi", "bus", "bicycle", "motor_scooter")); + +// make sure truck weight restrictions are not affected by the request parameter +TEST(CommonRestrictionsFail, Truck) { + + constexpr double gridsize = 500; + + const std::string ascii_map = R"( + A----------B-----C----D + )"; + + const auto layout = gurka::detail::map_to_coordinates(ascii_map, gridsize); + const gurka::ways ways = {{"AB", {{"highway", "residential"}}}, + {"BC", {{"highway", "residential"}, {"maxheight", "2.5"}}}, + {"CD", {{"highway", "residential"}}}}; + + gurka::map map = + gurka::buildtiles(layout, ways, {}, {}, "test/data/ignore_non_vehicular_restrictions_truck", + {{"mjolnir.timezone", {VALHALLA_BUILD_DIR "test/data/tz.sqlite"}}}); + + // too long + try { + valhalla::Api route = gurka::do_action(valhalla::Options::route, map, {"A", "D"}, "truck", + {{"/costing_options/truck/height", "3"}}); + + FAIL() << "Expected valhalla_exception_t."; + } catch (const valhalla_exception_t& err) { EXPECT_EQ(err.code, 442); } catch (...) { + FAIL() << "Expected to fail with a different error code."; + } + + // ...still too long + try { + valhalla::Api route = + gurka::do_action(valhalla::Options::route, map, {"A", "D"}, "truck", + {{"/costing_options/truck/ignore_non_vehicular_restrictions", "1"}, + {"/costing_options/truck/height", "3"}}); + FAIL() << "Expected no route to be found."; + + } catch (const valhalla_exception_t& err) { EXPECT_EQ(err.code, 442); } catch (...) { + FAIL() << "Expected to fail with a different error code."; + } +} \ No newline at end of file diff --git a/test/gurka/test_truck_restrictions.cc b/test/gurka/test_truck_restrictions.cc index 7368bb8dbf..9c11d099f4 100644 --- a/test/gurka/test_truck_restrictions.cc +++ b/test/gurka/test_truck_restrictions.cc @@ -49,6 +49,7 @@ TEST_P(TruckRestrictionTest, NotAllowed) { try { gurka::do_action(Options::route, map, {"A", "D"}, "truck", {{"/costing_options/truck/" + option, v}}); + FAIL() << "Expected no path to be found"; } catch (const valhalla_exception_t& err) { EXPECT_EQ(err.code, 442); } catch (...) { FAIL() << "Expected valhalla_exception_t."; }; @@ -65,7 +66,7 @@ INSTANTIATE_TEST_SUITE_P(TruckRestrictions, ::testing::Values(std::pair{"height", "6"}, std::pair{"width", "4"}, std::pair{"length", "30"}, - std::pair{"hazmat", "true"}, + std::pair{"hazmat", "1"}, std::pair{"axle_load", "11"}, std::pair{"axle_count", "10"})); diff --git a/valhalla/sif/dynamiccost.h b/valhalla/sif/dynamiccost.h index fb7ad7eaf0..441a64c1c5 100644 --- a/valhalla/sif/dynamiccost.h +++ b/valhalla/sif/dynamiccost.h @@ -87,6 +87,26 @@ : def)); \ } +/** + * same as above, but for costing options without pbf's awful oneof + * + * @param costing_options pointer to protobuf costing options object + * @param def the default value which is used when neither json nor pbf is provided + * @param json rapidjson value object which should contain user provided costing options + * @param json_key the json key to use to pull a user provided value out of the json + * @param option_name the name of the option will be set on the costing options object + */ + +#define JSON_PBF_DEFAULT_V2(costing_options, def, json, json_key, option_name) \ + { \ + costing_options->set_##option_name( \ + rapidjson::get::type>::type>(json, json_key, \ + costing_options->option_name() \ + ? costing_options->option_name() \ + : def)); \ + } + using namespace valhalla::midgard; namespace valhalla { @@ -427,6 +447,9 @@ class DynamicCost { thor::EdgeStatus* edgestatus = nullptr, const uint64_t current_time = 0, const uint32_t tz_index = 0) const { + if (ignore_turn_restrictions_) + return false; + // Lambda to get the next predecessor EdgeLabel (that is not a transition) auto next_predecessor = [&edge_labels](const EdgeLabel* label) { // Get the next predecessor - make sure it is valid. Continue to get @@ -596,9 +619,10 @@ class DynamicCost { const auto& restriction = restrictions[i]; // Compare the time to the time-based restrictions baldr::AccessType access_type = restriction.type(); - if (access_type == baldr::AccessType::kTimedAllowed || - access_type == baldr::AccessType::kTimedDenied || - access_type == baldr::AccessType::kDestinationAllowed) { + if (!ignore_non_vehicular_restrictions_ && + (access_type == baldr::AccessType::kTimedAllowed || + access_type == baldr::AccessType::kTimedDenied || + access_type == baldr::AccessType::kDestinationAllowed)) { // TODO: if(i > baldr::kInvalidRestriction) LOG_ERROR("restriction index overflow"); restriction_idx = static_cast(i); @@ -997,6 +1021,10 @@ class DynamicCost { bool shortest_; bool ignore_restrictions_{false}; + bool ignore_non_vehicular_restrictions_{false}; + // not a requestion parameter, it's true if either ignore_restrictions_ or + // ignore_non_vehicular_restrictions_ is true + bool ignore_turn_restrictions_{false}; bool ignore_oneways_{false}; bool ignore_access_{false}; bool ignore_closures_{false};