Skip to content

Commit 5c85096

Browse files
committed
Add mode-specific version of the maxStopCount parameter (maxStopCountForMode) to router-config.json.
1 parent d9398b6 commit 5c85096

File tree

4 files changed

+65
-19
lines changed

4 files changed

+65
-19
lines changed

application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/TransitRouter.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.opentripplanner.routing.algorithm.transferoptimization.configure.TransferOptimizationServiceConfigurator;
3737
import org.opentripplanner.routing.api.request.RouteRequest;
3838
import org.opentripplanner.routing.api.request.StreetMode;
39+
import org.opentripplanner.routing.api.request.preference.AccessEgressPreferences;
3940
import org.opentripplanner.routing.api.request.request.StreetRequest;
4041
import org.opentripplanner.routing.api.response.InputField;
4142
import org.opentripplanner.routing.api.response.RoutingError;
@@ -239,6 +240,7 @@ private Collection<? extends RoutingAccessEgress> fetchEgress() {
239240

240241
private Collection<? extends RoutingAccessEgress> fetchAccessEgresses(AccessEgressType type) {
241242
var streetRequest = type.isAccess() ? request.journey().access() : request.journey().egress();
243+
StreetMode mode = streetRequest.mode();
242244

243245
// Prepare access/egress lists
244246
RouteRequest accessRequest = request.clone();
@@ -252,13 +254,15 @@ private Collection<? extends RoutingAccessEgress> fetchAccessEgresses(AccessEgre
252254
});
253255
}
254256

255-
Duration durationLimit = accessRequest
257+
AccessEgressPreferences accessEgressPreferences = accessRequest
256258
.preferences()
257259
.street()
258-
.accessEgress()
259-
.maxDuration()
260-
.valueOf(streetRequest.mode());
261-
int stopCountLimit = accessRequest.preferences().street().accessEgress().maxStopCount();
260+
.accessEgress();
261+
262+
Duration durationLimit = accessEgressPreferences.maxDuration().valueOf(mode);
263+
int stopCountLimit = accessEgressPreferences
264+
.maxStopCountForMode()
265+
.getOrDefault(mode, accessEgressPreferences.defaultMaxStopCount());
262266

263267
var nearbyStops = AccessEgressRouter.findAccessEgresses(
264268
accessRequest,
@@ -275,7 +279,7 @@ private Collection<? extends RoutingAccessEgress> fetchAccessEgresses(AccessEgre
275279
var results = new ArrayList<>(accessEgresses);
276280

277281
// Special handling of flex accesses
278-
if (OTPFeature.FlexRouting.isOn() && streetRequest.mode() == StreetMode.FLEXIBLE) {
282+
if (OTPFeature.FlexRouting.isOn() && mode == StreetMode.FLEXIBLE) {
279283
var flexAccessList = FlexAccessEgressRouter.routeAccessEgress(
280284
accessRequest,
281285
temporaryVerticesContainer,

application/src/main/java/org/opentripplanner/routing/api/request/preference/AccessEgressPreferences.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import java.io.Serializable;
66
import java.time.Duration;
7+
import java.util.Collections;
78
import java.util.Map;
89
import java.util.Objects;
910
import java.util.function.Consumer;
@@ -27,18 +28,21 @@ public final class AccessEgressPreferences implements Serializable {
2728

2829
private final TimeAndCostPenaltyForEnum<StreetMode> penalty;
2930
private final DurationForEnum<StreetMode> maxDuration;
30-
private final int maxStopCount;
31+
private final int defaultMaxStopCount;
32+
private final Map<StreetMode, Integer> maxStopCountForMode;
3133

3234
private AccessEgressPreferences() {
3335
this.maxDuration = durationForStreetModeOf(ofMinutes(45));
3436
this.penalty = DEFAULT_TIME_AND_COST;
35-
this.maxStopCount = 500;
37+
this.defaultMaxStopCount = 500;
38+
this.maxStopCountForMode = Map.of();
3639
}
3740

3841
private AccessEgressPreferences(Builder builder) {
3942
this.maxDuration = builder.maxDuration;
4043
this.penalty = builder.penalty;
41-
this.maxStopCount = builder.maxStopCount;
44+
this.defaultMaxStopCount = builder.defaultMaxStopCount;
45+
this.maxStopCountForMode = Collections.unmodifiableMap(builder.maxStopCountForMode);
4246
}
4347

4448
public static Builder of() {
@@ -57,8 +61,12 @@ public DurationForEnum<StreetMode> maxDuration() {
5761
return maxDuration;
5862
}
5963

60-
public int maxStopCount() {
61-
return maxStopCount;
64+
public int defaultMaxStopCount() {
65+
return defaultMaxStopCount;
66+
}
67+
68+
public Map<StreetMode, Integer> maxStopCountForMode() {
69+
return maxStopCountForMode;
6270
}
6371

6472
@Override
@@ -69,13 +77,14 @@ public boolean equals(Object o) {
6977
return (
7078
penalty.equals(that.penalty) &&
7179
maxDuration.equals(that.maxDuration) &&
72-
maxStopCount == that.maxStopCount
80+
defaultMaxStopCount == that.defaultMaxStopCount &&
81+
maxStopCountForMode.equals(that.maxStopCountForMode)
7382
);
7483
}
7584

7685
@Override
7786
public int hashCode() {
78-
return Objects.hash(penalty, maxDuration, maxStopCount);
87+
return Objects.hash(penalty, maxDuration, defaultMaxStopCount, maxStopCountForMode);
7988
}
8089

8190
@Override
@@ -84,7 +93,8 @@ public String toString() {
8493
.of(AccessEgressPreferences.class)
8594
.addObj("penalty", penalty, DEFAULT.penalty)
8695
.addObj("maxDuration", maxDuration, DEFAULT.maxDuration)
87-
.addObj("maxStopCount", maxStopCount, DEFAULT.maxStopCount)
96+
.addObj("defaultMaxStopCount", defaultMaxStopCount, DEFAULT.defaultMaxStopCount)
97+
.addObj("maxStopCountForMode", maxStopCountForMode, DEFAULT.maxStopCountForMode)
8898
.toString();
8999
}
90100

@@ -93,13 +103,15 @@ public static class Builder {
93103
private final AccessEgressPreferences original;
94104
private TimeAndCostPenaltyForEnum<StreetMode> penalty;
95105
private DurationForEnum<StreetMode> maxDuration;
96-
private int maxStopCount;
106+
private Map<StreetMode, Integer> maxStopCountForMode;
107+
private int defaultMaxStopCount;
97108

98109
public Builder(AccessEgressPreferences original) {
99110
this.original = original;
100111
this.maxDuration = original.maxDuration;
101112
this.penalty = original.penalty;
102-
this.maxStopCount = original.maxStopCount;
113+
this.defaultMaxStopCount = original.defaultMaxStopCount;
114+
this.maxStopCountForMode = original.maxStopCountForMode;
103115
}
104116

105117
public Builder withMaxDuration(Consumer<DurationForEnum.Builder<StreetMode>> body) {
@@ -112,8 +124,12 @@ public Builder withMaxDuration(Duration defaultValue, Map<StreetMode, Duration>
112124
return withMaxDuration(b -> b.withDefault(defaultValue).withValues(values));
113125
}
114126

115-
public Builder withMaxStopCount(int maxCount) {
116-
this.maxStopCount = maxCount;
127+
public Builder withMaxStopCount(
128+
int defaultMaxStopCount,
129+
Map<StreetMode, Integer> maxStopCountForMode
130+
) {
131+
this.defaultMaxStopCount = defaultMaxStopCount;
132+
this.maxStopCountForMode = maxStopCountForMode;
117133
return this;
118134
}
119135

application/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,20 @@ duration can be set per mode(`maxDurationForMode`), because some street modes se
542542
Safety limit to prevent access to and egress from too many stops.
543543
"""
544544
)
545-
.asInt(dftAccessEgress.maxStopCount())
545+
.asInt(dftAccessEgress.defaultMaxStopCount()),
546+
cae
547+
.of("maxStopCountForMode")
548+
.since(V2_7)
549+
.summary(
550+
"Maximal number of stops collected in access/egress routing for the given mode"
551+
)
552+
.description(
553+
"""
554+
Safety limit to prevent access to and egress from too many stops.
555+
Mode-specific version of `maxStopCount`.
556+
"""
557+
)
558+
.asEnumMap(StreetMode.class, Integer.class)
546559
);
547560
})
548561
.withMaxDirectDuration(

doc/user/RouteRequest.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe
4646
|    [maxDuration](#rd_accessEgress_maxDuration) | `duration` | This is the maximum duration for access/egress for street searches. | *Optional* | `"PT45M"` | 2.1 |
4747
|    [maxStopCount](#rd_accessEgress_maxStopCount) | `integer` | Maximal number of stops collected in access/egress routing | *Optional* | `500` | 2.4 |
4848
|    [maxDurationForMode](#rd_accessEgress_maxDurationForMode) | `enum map of duration` | Limit access/egress per street mode. | *Optional* | | 2.1 |
49+
|    [maxStopCountForMode](#rd_accessEgress_maxStopCountForMode) | `enum map of integer` | Maximal number of stops collected in access/egress routing for the given mode | *Optional* | | 2.7 |
4950
|    [penalty](#rd_accessEgress_penalty) | `enum map of object` | Penalty for access/egress by street mode. | *Optional* | | 2.4 |
5051
|       FLEXIBLE | `object` | NA | *Optional* | | 2.4 |
5152
|          costFactor | `double` | A factor multiplied with the time-penalty to get the cost-penalty. | *Optional* | `0.0` | 2.4 |
@@ -431,6 +432,18 @@ Override the settings in `maxDuration` for specific street modes. This is
431432
done because some street modes searches are much more resource intensive than others.
432433

433434

435+
<h3 id="rd_accessEgress_maxStopCountForMode">maxStopCountForMode</h3>
436+
437+
**Since version:** `2.7`**Type:** `enum map of integer`**Cardinality:** `Optional`
438+
**Path:** /routingDefaults/accessEgress
439+
**Enum keys:** `not-set` | `walk` | `bike` | `bike-to-park` | `bike-rental` | `scooter-rental` | `car` | `car-to-park` | `car-pickup` | `car-rental` | `car-hailing` | `flexible`
440+
441+
Maximal number of stops collected in access/egress routing for the given mode
442+
443+
Safety limit to prevent access to and egress from too many stops.
444+
Mode-specific version of `maxStopCount`.
445+
446+
434447
<h3 id="rd_accessEgress_penalty">penalty</h3>
435448

436449
**Since version:** `2.4`**Type:** `enum map of object`**Cardinality:** `Optional`

0 commit comments

Comments
 (0)