Skip to content

Commit

Permalink
Add mode-specific version of the maxStopCount parameter (maxStopCount…
Browse files Browse the repository at this point in the history
…ForMode) to router-config.json.
  • Loading branch information
VillePihlava committed Jan 14, 2025
1 parent d9398b6 commit 5c85096
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.opentripplanner.routing.algorithm.transferoptimization.configure.TransferOptimizationServiceConfigurator;
import org.opentripplanner.routing.api.request.RouteRequest;
import org.opentripplanner.routing.api.request.StreetMode;
import org.opentripplanner.routing.api.request.preference.AccessEgressPreferences;
import org.opentripplanner.routing.api.request.request.StreetRequest;
import org.opentripplanner.routing.api.response.InputField;
import org.opentripplanner.routing.api.response.RoutingError;
Expand Down Expand Up @@ -239,6 +240,7 @@ private Collection<? extends RoutingAccessEgress> fetchEgress() {

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

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

Duration durationLimit = accessRequest
AccessEgressPreferences accessEgressPreferences = accessRequest
.preferences()
.street()
.accessEgress()
.maxDuration()
.valueOf(streetRequest.mode());
int stopCountLimit = accessRequest.preferences().street().accessEgress().maxStopCount();
.accessEgress();

Duration durationLimit = accessEgressPreferences.maxDuration().valueOf(mode);
int stopCountLimit = accessEgressPreferences
.maxStopCountForMode()
.getOrDefault(mode, accessEgressPreferences.defaultMaxStopCount());

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

// Special handling of flex accesses
if (OTPFeature.FlexRouting.isOn() && streetRequest.mode() == StreetMode.FLEXIBLE) {
if (OTPFeature.FlexRouting.isOn() && mode == StreetMode.FLEXIBLE) {
var flexAccessList = FlexAccessEgressRouter.routeAccessEgress(
accessRequest,
temporaryVerticesContainer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.io.Serializable;
import java.time.Duration;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
Expand All @@ -27,18 +28,21 @@ public final class AccessEgressPreferences implements Serializable {

private final TimeAndCostPenaltyForEnum<StreetMode> penalty;
private final DurationForEnum<StreetMode> maxDuration;
private final int maxStopCount;
private final int defaultMaxStopCount;
private final Map<StreetMode, Integer> maxStopCountForMode;

private AccessEgressPreferences() {
this.maxDuration = durationForStreetModeOf(ofMinutes(45));
this.penalty = DEFAULT_TIME_AND_COST;
this.maxStopCount = 500;
this.defaultMaxStopCount = 500;
this.maxStopCountForMode = Map.of();
}

private AccessEgressPreferences(Builder builder) {
this.maxDuration = builder.maxDuration;
this.penalty = builder.penalty;
this.maxStopCount = builder.maxStopCount;
this.defaultMaxStopCount = builder.defaultMaxStopCount;
this.maxStopCountForMode = Collections.unmodifiableMap(builder.maxStopCountForMode);
}

public static Builder of() {
Expand All @@ -57,8 +61,12 @@ public DurationForEnum<StreetMode> maxDuration() {
return maxDuration;
}

public int maxStopCount() {
return maxStopCount;
public int defaultMaxStopCount() {
return defaultMaxStopCount;
}

public Map<StreetMode, Integer> maxStopCountForMode() {
return maxStopCountForMode;
}

@Override
Expand All @@ -69,13 +77,14 @@ public boolean equals(Object o) {
return (
penalty.equals(that.penalty) &&
maxDuration.equals(that.maxDuration) &&
maxStopCount == that.maxStopCount
defaultMaxStopCount == that.defaultMaxStopCount &&
maxStopCountForMode.equals(that.maxStopCountForMode)
);
}

@Override
public int hashCode() {
return Objects.hash(penalty, maxDuration, maxStopCount);
return Objects.hash(penalty, maxDuration, defaultMaxStopCount, maxStopCountForMode);
}

@Override
Expand All @@ -84,7 +93,8 @@ public String toString() {
.of(AccessEgressPreferences.class)
.addObj("penalty", penalty, DEFAULT.penalty)
.addObj("maxDuration", maxDuration, DEFAULT.maxDuration)
.addObj("maxStopCount", maxStopCount, DEFAULT.maxStopCount)
.addObj("defaultMaxStopCount", defaultMaxStopCount, DEFAULT.defaultMaxStopCount)
.addObj("maxStopCountForMode", maxStopCountForMode, DEFAULT.maxStopCountForMode)
.toString();
}

Expand All @@ -93,13 +103,15 @@ public static class Builder {
private final AccessEgressPreferences original;
private TimeAndCostPenaltyForEnum<StreetMode> penalty;
private DurationForEnum<StreetMode> maxDuration;
private int maxStopCount;
private Map<StreetMode, Integer> maxStopCountForMode;
private int defaultMaxStopCount;

public Builder(AccessEgressPreferences original) {
this.original = original;
this.maxDuration = original.maxDuration;
this.penalty = original.penalty;
this.maxStopCount = original.maxStopCount;
this.defaultMaxStopCount = original.defaultMaxStopCount;
this.maxStopCountForMode = original.maxStopCountForMode;
}

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

public Builder withMaxStopCount(int maxCount) {
this.maxStopCount = maxCount;
public Builder withMaxStopCount(
int defaultMaxStopCount,
Map<StreetMode, Integer> maxStopCountForMode
) {
this.defaultMaxStopCount = defaultMaxStopCount;
this.maxStopCountForMode = maxStopCountForMode;
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,20 @@ duration can be set per mode(`maxDurationForMode`), because some street modes se
Safety limit to prevent access to and egress from too many stops.
"""
)
.asInt(dftAccessEgress.maxStopCount())
.asInt(dftAccessEgress.defaultMaxStopCount()),
cae
.of("maxStopCountForMode")
.since(V2_7)
.summary(
"Maximal number of stops collected in access/egress routing for the given mode"
)
.description(
"""
Safety limit to prevent access to and egress from too many stops.
Mode-specific version of `maxStopCount`.
"""
)
.asEnumMap(StreetMode.class, Integer.class)
);
})
.withMaxDirectDuration(
Expand Down
13 changes: 13 additions & 0 deletions doc/user/RouteRequest.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe
|    [maxDuration](#rd_accessEgress_maxDuration) | `duration` | This is the maximum duration for access/egress for street searches. | *Optional* | `"PT45M"` | 2.1 |
|    [maxStopCount](#rd_accessEgress_maxStopCount) | `integer` | Maximal number of stops collected in access/egress routing | *Optional* | `500` | 2.4 |
|    [maxDurationForMode](#rd_accessEgress_maxDurationForMode) | `enum map of duration` | Limit access/egress per street mode. | *Optional* | | 2.1 |
|    [maxStopCountForMode](#rd_accessEgress_maxStopCountForMode) | `enum map of integer` | Maximal number of stops collected in access/egress routing for the given mode | *Optional* | | 2.7 |
|    [penalty](#rd_accessEgress_penalty) | `enum map of object` | Penalty for access/egress by street mode. | *Optional* | | 2.4 |
|       FLEXIBLE | `object` | NA | *Optional* | | 2.4 |
|          costFactor | `double` | A factor multiplied with the time-penalty to get the cost-penalty. | *Optional* | `0.0` | 2.4 |
Expand Down Expand Up @@ -431,6 +432,18 @@ Override the settings in `maxDuration` for specific street modes. This is
done because some street modes searches are much more resource intensive than others.


<h3 id="rd_accessEgress_maxStopCountForMode">maxStopCountForMode</h3>

**Since version:** `2.7`**Type:** `enum map of integer`**Cardinality:** `Optional`
**Path:** /routingDefaults/accessEgress
**Enum keys:** `not-set` | `walk` | `bike` | `bike-to-park` | `bike-rental` | `scooter-rental` | `car` | `car-to-park` | `car-pickup` | `car-rental` | `car-hailing` | `flexible`

Maximal number of stops collected in access/egress routing for the given mode

Safety limit to prevent access to and egress from too many stops.
Mode-specific version of `maxStopCount`.


<h3 id="rd_accessEgress_penalty">penalty</h3>

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

0 comments on commit 5c85096

Please sign in to comment.