Skip to content

Commit a5a3ba6

Browse files
authored
Add configurable max_collapse_distance property to Lua profiles for p… (#7344)
* Add configurable max_collapse_distance property to Lua profiles for pedestrian routing * Add log entry * Fix format * Remove defaults, move init to constructor, pass max_collapse_distance * Add missing GetMaxCollapseDistance
1 parent e248005 commit a5a3ba6

13 files changed

Lines changed: 161 additions & 77 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
- Routing:
44
- FIXED: Crash when route starts or ends at `type=manoeuvre` relation via node [#7287](https://github.com/Project-OSRM/osrm-backend/issues/7287)
55
- Profiles:
6+
- ADDED: Make `max_collapse_distance` configurable via Lua profiles to preserve short road crossings in pedestrian routing [#6171](https://github.com/Project-OSRM/osrm-backend/issues/6171)
67
- ADDED: Add exception for audible fences (`barrier=fence` with `sensory=audible` or `sensory=audio`) that deter livestock but do not block vehicles [#6964](https://github.com/Project-OSRM/osrm-backend/issues/6964)
78
- ADDED: Use `is_sidepath:of:name` and `street:name` as fallback names for unnamed sidewalks and sidepaths in foot and bicycle profiles [#7259](https://github.com/Project-OSRM/osrm-backend/issues/7259)
89
- Build:

include/engine/api/route_api.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,9 @@ class RouteAPI : public BaseAPI
945945
guidance::applyOverrides(BaseAPI::facade, steps, leg_geometry);
946946

947947
// Collapse segregated steps before others
948-
steps = guidance::collapseSegregatedTurnInstructions(std::move(steps));
948+
const auto max_collapse_distance = BaseAPI::facade.GetMaxCollapseDistance();
949+
steps = guidance::collapseSegregatedTurnInstructions(std::move(steps),
950+
max_collapse_distance);
949951

950952
/* Perform step-based post-processing.
951953
*
@@ -979,7 +981,8 @@ class RouteAPI : public BaseAPI
979981

980982
guidance::trimShortSegments(steps, leg_geometry);
981983
leg.steps = guidance::handleRoundabouts(std::move(steps));
982-
leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps));
984+
leg.steps = guidance::collapseTurnInstructions(std::move(leg.steps),
985+
max_collapse_distance);
983986
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
984987
leg.steps = guidance::buildIntersections(std::move(leg.steps));
985988
leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps));

include/engine/datafacade/contiguous_internalmem_datafacade.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
499499
return m_profile_properties->max_speed_for_map_matching;
500500
}
501501

502+
double GetMaxCollapseDistance() const override final
503+
{
504+
return m_profile_properties->GetMaxCollapseDistance();
505+
}
506+
502507
const char *GetWeightName() const override final { return m_profile_properties->weight_name; }
503508

504509
unsigned GetWeightPrecision() const override final

include/engine/datafacade/datafacade_base.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ class BaseDataFacade
164164

165165
virtual double GetMapMatchingMaxSpeed() const = 0;
166166

167+
virtual double GetMaxCollapseDistance() const = 0;
168+
167169
virtual const char *GetWeightName() const = 0;
168170

169171
virtual unsigned GetWeightPrecision() const = 0;

include/engine/guidance/collapse_scenario_detection.hpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ bool isStaggeredIntersection(const RouteStepIterator step_prior_to_intersection,
3232
// a - > x
3333
bool isUTurn(const RouteStepIterator step_prior_to_intersection,
3434
const RouteStepIterator step_entering_intersection,
35-
const RouteStepIterator step_leaving_intersection);
35+
const RouteStepIterator step_leaving_intersection,
36+
double max_collapse_distance);
3637

3738
// detect oscillating names where a name switch A->B->A occurs. This is often the case due to
3839
// bridges or tunnels. Any such oszillation is not supposed to show up
@@ -51,25 +52,33 @@ bool isNameOszillation(const RouteStepIterator step_prior_to_intersection,
5152
// the road turns right after. The offset would only be there due to the broad road at `e`
5253
bool maneuverPreceededByNameChange(const RouteStepIterator step_prior_to_intersection,
5354
const RouteStepIterator step_entering_intersection,
54-
const RouteStepIterator step_leaving_intersection);
55+
const RouteStepIterator step_leaving_intersection,
56+
double max_collapse_distance);
5557
bool maneuverPreceededBySuppressedDirection(const RouteStepIterator step_entering_intersection,
56-
const RouteStepIterator step_leaving_intersection);
58+
const RouteStepIterator step_leaving_intersection,
59+
double max_collapse_distance);
5760
bool suppressedStraightBetweenTurns(const RouteStepIterator step_entering_intersection,
5861
const RouteStepIterator step_at_center_of_intersection,
59-
const RouteStepIterator step_leaving_intersection);
62+
const RouteStepIterator step_leaving_intersection,
63+
double max_collapse_distance);
6064

6165
bool maneuverSucceededByNameChange(const RouteStepIterator step_entering_intersection,
62-
const RouteStepIterator step_leaving_intersection);
66+
const RouteStepIterator step_leaving_intersection,
67+
double max_collapse_distance);
6368
bool maneuverSucceededBySuppressedDirection(const RouteStepIterator step_entering_intersection,
64-
const RouteStepIterator step_leaving_intersection);
69+
const RouteStepIterator step_leaving_intersection,
70+
double max_collapse_distance);
6571
bool nameChangeImmediatelyAfterSuppressed(const RouteStepIterator step_entering_intersection,
66-
const RouteStepIterator step_leaving_intersection);
72+
const RouteStepIterator step_leaving_intersection,
73+
double max_collapse_distance);
6774
bool closeChoicelessTurnAfterTurn(const RouteStepIterator step_entering_intersection,
68-
const RouteStepIterator step_leaving_intersection);
75+
const RouteStepIterator step_leaving_intersection,
76+
double max_collapse_distance);
6977
// if modelled turn roads meet in the center of a segregated intersection, we can end up with double
7078
// choiceless turns
7179
bool doubleChoiceless(const RouteStepIterator step_entering_intersection,
72-
const RouteStepIterator step_leaving_intersection);
80+
const RouteStepIterator step_leaving_intersection,
81+
double max_collapse_distance);
7382

7483
// Due to obvious detection, sometimes we can have straight turns followed by a different turn right
7584
// next to each other. We combine both turns into one, if the second turn is without choice
@@ -81,7 +90,8 @@ bool doubleChoiceless(const RouteStepIterator step_entering_intersection,
8190
// with a main road `abd`, the turn `continue straight` at `b` and `turn left at `c` will become a
8291
// `turn left` at `b`
8392
bool straightTurnFollowedByChoiceless(const RouteStepIterator step_entering_intersection,
84-
const RouteStepIterator step_leaving_intersection);
93+
const RouteStepIterator step_leaving_intersection,
94+
double max_collapse_distance);
8595

8696
} // namespace osrm::engine::guidance
8797

include/engine/guidance/collapse_turns.hpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@ namespace osrm::engine::guidance
1111
// Multiple possible reasons can result in unnecessary/confusing instructions
1212
// Collapsing such turns into a single turn instruction, we give a clearer
1313
// set of instructions that is not cluttered by unnecessary turns/name changes.
14-
[[nodiscard]] std::vector<RouteStep> collapseTurnInstructions(std::vector<RouteStep> steps);
14+
[[nodiscard]] std::vector<RouteStep> collapseTurnInstructions(std::vector<RouteStep> steps,
15+
double max_collapse_distance);
1516

1617
// Multiple possible reasons can result in unnecessary/confusing instructions
1718
// A prime example would be a segregated intersection. Turning around at this
1819
// intersection would result in two instructions to turn left.
1920
// Collapsing such turns into a single turn instruction, we give a clearer
2021
// set of instructions that is not cluttered by unnecessary turns/name changes.
2122
[[nodiscard]] std::vector<RouteStep>
22-
collapseSegregatedTurnInstructions(std::vector<RouteStep> steps);
23+
collapseSegregatedTurnInstructions(std::vector<RouteStep> steps, double max_collapse_distance);
2324

2425
// A combined turn is a set of two instructions that actually form a single turn, as far as we
2526
// perceive it. A u-turn consisting of two left turns is one such example. But there are also lots
@@ -62,16 +63,21 @@ struct TransferTurnTypeStrategy : CombineStrategy
6263
// Combine both turn and turn angle to a common item
6364
struct AdjustToCombinedTurnAngleStrategy : CombineStrategy
6465
{
66+
AdjustToCombinedTurnAngleStrategy(double max_collapse_distance);
6567
void operator()(RouteStep &step_at_turn_location, const RouteStep &transfer_from_step) const;
68+
69+
double max_collapse_distance;
6670
};
6771

6872
// Combine only the turn types
6973
struct AdjustToCombinedTurnStrategy : CombineStrategy
7074
{
71-
AdjustToCombinedTurnStrategy(const RouteStep &step_prior_to_intersection);
75+
AdjustToCombinedTurnStrategy(const RouteStep &step_prior_to_intersection,
76+
double max_collapse_distance);
7277
void operator()(RouteStep &step_at_turn_location, const RouteStep &transfer_from_step) const;
7378

7479
const RouteStep &step_prior_to_intersection;
80+
double max_collapse_distance;
7581
};
7682

7783
// Set a fixed instruction type

include/extractor/profile_properties.hpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ struct ProfileProperties
2525

2626
ProfileProperties()
2727
: traffic_signal_penalty(0), u_turn_penalty(0),
28-
max_speed_for_map_matching(DEFAULT_MAX_SPEED), continue_straight_at_waypoint(true),
29-
use_turn_restrictions(false), left_hand_driving(false), fallback_to_duration(true),
30-
weight_name{"duration"}, class_names{{}}, excludable_classes{{}},
31-
call_tagless_node_function(true)
28+
max_speed_for_map_matching(DEFAULT_MAX_SPEED), max_collapse_distance(30.0),
29+
continue_straight_at_waypoint(true), use_turn_restrictions(false),
30+
left_hand_driving(false), fallback_to_duration(true), weight_name{"duration"},
31+
class_names{{}}, excludable_classes{{}}, call_tagless_node_function(true)
3232
{
3333
std::fill(excludable_classes.begin(), excludable_classes.end(), INVALID_CLASS_DATA);
3434
BOOST_ASSERT(weight_name[MAX_WEIGHT_NAME_LENGTH] == '\0');
@@ -55,6 +55,13 @@ struct ProfileProperties
5555
max_speed_for_map_matching = max_speed_for_map_matching_;
5656
}
5757

58+
double GetMaxCollapseDistance() const { return max_collapse_distance; }
59+
60+
void SetMaxCollapseDistance(const double max_collapse_distance_)
61+
{
62+
max_collapse_distance = max_collapse_distance_;
63+
}
64+
5865
void SetWeightName(const std::string &name)
5966
{
6067
auto count = std::min<std::size_t>(name.length(), MAX_WEIGHT_NAME_LENGTH) + 1;
@@ -120,6 +127,8 @@ struct ProfileProperties
120127
//! penalty to do a uturn in deci-seconds
121128
std::int32_t u_turn_penalty;
122129
double max_speed_for_map_matching;
130+
//! maximum distance in meters to collapse route steps (default 30m, intended for cars)
131+
double max_collapse_distance;
123132
//! depending on the profile, force the routing to always continue in the same direction
124133
bool continue_straight_at_waypoint;
125134
//! flag used for restriction parser (e.g. used for the walk profile)

profiles/foot.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ function setup()
1818
u_turn_penalty = 2,
1919
continue_straight_at_waypoint = false,
2020
use_turn_restrictions = false,
21+
-- preserve short road crossings for pedestrian safety analysis
22+
max_collapse_distance = 10,
2123
},
2224

2325
default_mode = mode.walking,

0 commit comments

Comments
 (0)