From 1ba569ab7328f2621d00b3eaff28dad6b4da2b45 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 18 Dec 2023 17:30:07 +0200 Subject: [PATCH 01/21] Introduce vehicle walking preferences --- .../common/RequestToPreferencesMapper.java | 10 +- .../apis/gtfs/mapping/RouteRequestMapper.java | 16 +- .../preferences/BikePreferencesMapper.java | 2 +- .../request/preference/BikePreferences.java | 128 ++---------- .../preference/RoutingPreferences.java | 2 +- .../preference/VehicleWalkingPreferences.java | 185 ++++++++++++++++++ .../street/model/edge/BikeWalkableEdge.java | 8 +- .../street/model/edge/StreetEdge.java | 6 +- .../edge/StreetEdgeReluctanceCalculator.java | 4 +- .../BikePreferencesMapperTest.java | 2 +- .../preference/BikePreferencesTest.java | 28 --- .../VehicleWalkingPreferencesTest.java | 77 ++++++++ .../integration/BarrierRoutingTest.java | 5 +- .../street/integration/BikeWalkingTest.java | 2 +- .../street/model/edge/StreetEdgeCostTest.java | 4 +- .../street/model/edge/StreetEdgeTest.java | 12 +- 16 files changed, 325 insertions(+), 166 deletions(-) create mode 100644 src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java create mode 100644 src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java diff --git a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java index 6ccc8d3ca47..68e61d6fe4e 100644 --- a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java @@ -67,10 +67,6 @@ private void mapBike() { setIfNotNull(req.bikeSpeed, bike::withSpeed); setIfNotNull(req.bikeReluctance, bike::withReluctance); setIfNotNull(req.bikeBoardCost, bike::withBoardCost); - setIfNotNull(req.bikeWalkingSpeed, bike::withWalkingSpeed); - setIfNotNull(req.bikeWalkingReluctance, bike::withWalkingReluctance); - setIfNotNull(req.bikeSwitchTime, bike::withSwitchTime); - setIfNotNull(req.bikeSwitchCost, bike::withSwitchCost); setIfNotNull(req.bikeOptimizeType, bike::withOptimizeType); if (req.bikeOptimizeType == BicycleOptimizeType.TRIANGLE) { @@ -87,6 +83,12 @@ private void mapBike() { setIfNotNull(req.bikeParkTime, parking::withParkTime); }); bike.withRental(this::mapRental); + bike.withWalking(walk -> { + setIfNotNull(req.bikeWalkingSpeed, walk::withSpeed); + setIfNotNull(req.bikeWalkingReluctance, walk::withReluctance); + setIfNotNull(req.bikeSwitchTime, walk::withHopTime); + setIfNotNull(req.bikeSwitchCost, walk::withHopCost); + }); }); } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java index 790064aba22..a12ef45f6fb 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java @@ -23,6 +23,7 @@ import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; import org.opentripplanner.routing.api.request.preference.VehicleRentalPreferences; +import org.opentripplanner.routing.api.request.preference.VehicleWalkingPreferences; import org.opentripplanner.routing.api.request.request.filter.SelectRequest; import org.opentripplanner.routing.api.request.request.filter.TransitFilterRequest; import org.opentripplanner.routing.core.BicycleOptimizeType; @@ -66,11 +67,7 @@ public static RouteRequest toRouteRequest( request.withPreferences(preferences -> { preferences.withBike(bike -> { callWith.argument("bikeReluctance", bike::withReluctance); - callWith.argument("bikeWalkingReluctance", bike::withWalkingReluctance); - callWith.argument("bikeWalkingSpeed", bike::withWalkingSpeed); callWith.argument("bikeSpeed", bike::withSpeed); - callWith.argument("bikeSwitchTime", bike::withSwitchTime); - callWith.argument("bikeSwitchCost", bike::withSwitchCost); callWith.argument("bikeBoardCost", bike::withBoardCost); if (environment.getArgument("optimize") != null) { @@ -86,6 +83,7 @@ public static RouteRequest toRouteRequest( bike.withParking(parking -> setParkingPreferences(callWith, parking)); bike.withRental(rental -> setRentalPreferences(callWith, request, rental)); + bike.withWalking(walking -> setVehicleWalkingPreferences(callWith, walking)); }); preferences.withCar(car -> { @@ -330,6 +328,16 @@ private static void setRentalPreferences( ); } + private static void setVehicleWalkingPreferences( + CallerWithEnvironment callWith, + VehicleWalkingPreferences.Builder walking + ) { + callWith.argument("bikeWalkingReluctance", walking::withReluctance); + callWith.argument("bikeWalkingSpeed", walking::withSpeed); + callWith.argument("bikeSwitchTime", time -> walking.withHopTime((int) time)); + callWith.argument("bikeSwitchCost", cost -> walking.withHopCost((int) cost)); + } + private static class CallerWithEnvironment { private final DataFetchingEnvironment environment; diff --git a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java index 3ccdd9007a4..1179c034e93 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapper.java @@ -27,7 +27,7 @@ public static void mapBikePreferences( "walkReluctance", r -> { bike.withReluctance((double) r); - bike.withWalkingReluctance(WALK_BIKE_RELATIVE_RELUCTANCE * (double) r); + bike.withWalking(w -> w.withReluctance(WALK_BIKE_RELATIVE_RELUCTANCE * (double) r)); } ); diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java index 5717876bbfc..f282e02340c 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java @@ -25,45 +25,32 @@ public final class BikePreferences implements Serializable { private final double speed; private final double reluctance; private final Cost boardCost; - private final double walkingSpeed; - private final double walkingReluctance; - private final int switchTime; - private final Cost switchCost; private final VehicleParkingPreferences parking; private final VehicleRentalPreferences rental; - private final double stairsReluctance; private final BicycleOptimizeType optimizeType; private final TimeSlopeSafetyTriangle optimizeTriangle; + private final VehicleWalkingPreferences walking; private BikePreferences() { this.speed = 5; this.reluctance = 2.0; this.boardCost = Cost.costOfMinutes(10); - this.walkingSpeed = 1.33; - this.walkingReluctance = 5.0; - this.switchTime = 0; - this.switchCost = Cost.ZERO; this.parking = VehicleParkingPreferences.DEFAULT; this.rental = VehicleRentalPreferences.DEFAULT; this.optimizeType = BicycleOptimizeType.SAFE; this.optimizeTriangle = TimeSlopeSafetyTriangle.DEFAULT; - // very high reluctance to carry the bike up/down a flight of stairs - this.stairsReluctance = 10; + this.walking = VehicleWalkingPreferences.DEFAULT; } private BikePreferences(Builder builder) { this.speed = Units.speed(builder.speed); this.reluctance = Units.reluctance(builder.reluctance); this.boardCost = builder.boardCost; - this.walkingSpeed = Units.speed(builder.walkingSpeed); - this.walkingReluctance = Units.reluctance(builder.walkingReluctance); - this.switchTime = Units.duration(builder.switchTime); - this.switchCost = builder.switchCost; this.parking = builder.parking; this.rental = builder.rental; this.optimizeType = Objects.requireNonNull(builder.optimizeType); this.optimizeTriangle = Objects.requireNonNull(builder.optimizeTriangle); - this.stairsReluctance = Units.reluctance(builder.stairsReluctance); + this.walking = builder.walking; } public static BikePreferences.Builder of() { @@ -94,36 +81,6 @@ public int boardCost() { return boardCost.toSeconds(); } - /** - * The walking speed when walking a bike. Default: 1.33 m/s ~ Same as walkSpeed - */ - public double walkingSpeed() { - return walkingSpeed; - } - - /** - * A multiplier for how bad walking is, compared to being in transit for equal - * lengths of time. Empirically, values between 2 and 4 seem to correspond - * well to the concept of not wanting to walk too much without asking for - * totally ridiculous itineraries, but this observation should in no way be - * taken as scientific or definitive. Your mileage may vary. See - * https://github.com/opentripplanner/OpenTripPlanner/issues/4090 for impact on - * performance with high values. Default value: 2.0 - */ - public double walkingReluctance() { - return walkingReluctance; - } - - /** Time to get on and off your own bike */ - public int switchTime() { - return switchTime; - } - - /** Cost of getting on and off your own bike */ - public int switchCost() { - return switchCost.toSeconds(); - } - /** Parking preferences that can be different per request */ public VehicleParkingPreferences parking() { return parking; @@ -145,8 +102,9 @@ public TimeSlopeSafetyTriangle optimizeTriangle() { return optimizeTriangle; } - public double stairsReluctance() { - return stairsReluctance; + /** Bike walking preferences that can be different per request */ + public VehicleWalkingPreferences walking() { + return walking; } @Override @@ -158,15 +116,11 @@ public boolean equals(Object o) { doubleEquals(that.speed, speed) && doubleEquals(that.reluctance, reluctance) && boardCost.equals(that.boardCost) && - doubleEquals(that.walkingSpeed, walkingSpeed) && - doubleEquals(that.walkingReluctance, walkingReluctance) && - switchTime == that.switchTime && - switchCost.equals(that.switchCost) && - parking.equals(that.parking) && - rental.equals(that.rental) && + Objects.equals(parking, that.parking) && + Objects.equals(rental, that.rental) && optimizeType == that.optimizeType && optimizeTriangle.equals(that.optimizeTriangle) && - doubleEquals(stairsReluctance, that.stairsReluctance) + Objects.equals(walking, that.walking) ); } @@ -176,15 +130,11 @@ public int hashCode() { speed, reluctance, boardCost, - walkingSpeed, - walkingReluctance, - switchTime, - switchCost, parking, rental, optimizeType, optimizeTriangle, - stairsReluctance + walking ); } @@ -195,15 +145,11 @@ public String toString() { .addNum("speed", speed, DEFAULT.speed) .addNum("reluctance", reluctance, DEFAULT.reluctance) .addObj("boardCost", boardCost, DEFAULT.boardCost) - .addNum("walkingSpeed", walkingSpeed, DEFAULT.walkingSpeed) - .addNum("walkingReluctance", walkingReluctance, DEFAULT.walkingReluctance) - .addDurationSec("switchTime", switchTime, DEFAULT.switchTime) - .addObj("switchCost", switchCost, DEFAULT.switchCost) .addObj("parking", parking, DEFAULT.parking) .addObj("rental", rental, DEFAULT.rental) .addEnum("optimizeType", optimizeType, DEFAULT.optimizeType) .addObj("optimizeTriangle", optimizeTriangle, DEFAULT.optimizeTriangle) - .addNum("stairsReluctance", stairsReluctance, DEFAULT.stairsReluctance) + .addObj("walking", walking, DEFAULT.walking) .toString(); } @@ -214,31 +160,23 @@ public static class Builder { private double speed; private double reluctance; private Cost boardCost; - private double walkingSpeed; - private double walkingReluctance; - private int switchTime; - private Cost switchCost; private VehicleParkingPreferences parking; private VehicleRentalPreferences rental; private BicycleOptimizeType optimizeType; private TimeSlopeSafetyTriangle optimizeTriangle; - public double stairsReluctance; + public VehicleWalkingPreferences walking; public Builder(BikePreferences original) { this.original = original; this.speed = original.speed; this.reluctance = original.reluctance; this.boardCost = original.boardCost; - this.walkingSpeed = original.walkingSpeed; - this.walkingReluctance = original.walkingReluctance; - this.switchTime = original.switchTime; - this.switchCost = original.switchCost; this.parking = original.parking; this.rental = original.rental; this.optimizeType = original.optimizeType; this.optimizeTriangle = original.optimizeTriangle; - this.stairsReluctance = original.stairsReluctance; + this.walking = original.walking; } public BikePreferences original() { @@ -272,42 +210,6 @@ public Builder withBoardCost(int boardCost) { return this; } - public double walkingSpeed() { - return walkingSpeed; - } - - public Builder withWalkingSpeed(double walkingSpeed) { - this.walkingSpeed = walkingSpeed; - return this; - } - - public double walkingReluctance() { - return walkingReluctance; - } - - public Builder withWalkingReluctance(double walkingReluctance) { - this.walkingReluctance = walkingReluctance; - return this; - } - - public int switchTime() { - return switchTime; - } - - public Builder withSwitchTime(int switchTime) { - this.switchTime = switchTime; - return this; - } - - public Cost switchCost() { - return switchCost; - } - - public Builder withSwitchCost(int switchCost) { - this.switchCost = Cost.costOfSeconds(switchCost); - return this; - } - public Builder withParking(Consumer body) { this.parking = ifNotNull(this.parking, original.parking).copyOf().apply(body).build(); return this; @@ -338,8 +240,8 @@ public Builder withOptimizeTriangle(Consumer bo return this; } - public Builder withStairsReluctance(double value) { - this.stairsReluctance = value; + public Builder withWalking(Consumer body) { + this.walking = ifNotNull(this.walking, original.walking).copyOf().apply(body).build(); return this; } diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java index 3230bbf5968..d3d22160935 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/RoutingPreferences.java @@ -129,7 +129,7 @@ public SystemPreferences system() { */ public double getSpeed(TraverseMode mode, boolean walkingBike) { return switch (mode) { - case WALK -> walkingBike ? bike.walkingSpeed() : walk.speed(); + case WALK -> walkingBike ? bike.walking().speed() : walk.speed(); case BICYCLE -> bike.speed(); case CAR -> car.speed(); default -> throw new IllegalArgumentException("getSpeed(): Invalid mode " + mode); diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java new file mode 100644 index 00000000000..0abf2926f42 --- /dev/null +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java @@ -0,0 +1,185 @@ +package org.opentripplanner.routing.api.request.preference; + +import java.io.Serializable; +import java.time.Duration; +import java.util.Objects; +import java.util.function.Consumer; +import org.opentripplanner.framework.model.Cost; +import org.opentripplanner.framework.model.Units; +import org.opentripplanner.framework.tostring.ToStringBuilder; + +/** + * Preferences for walking a vehicle. + *

+ * THIS CLASS IS IMMUTABLE AND THREAD-SAFE. + */ +public class VehicleWalkingPreferences implements Serializable { + + public static final VehicleWalkingPreferences DEFAULT = new VehicleWalkingPreferences(); + + private final double speed; + private final double reluctance; + private final Duration hopTime; + private final Cost hopCost; + private final double stairsReluctance; + + private VehicleWalkingPreferences() { + this.speed = 1.33; + this.reluctance = 5.0; + this.hopTime = Duration.ZERO; + this.hopCost = Cost.ZERO; + // very high reluctance to carry the bike up/down a flight of stairs + this.stairsReluctance = 10; + } + + /** + * Sets the vehicle walking preferences and does some input value validation and rounds + * reluctances and speed to not have too many decimals. + */ + private VehicleWalkingPreferences(Builder builder) { + this.speed = Units.speed(builder.speed); + this.reluctance = Units.reluctance(builder.reluctance); + this.hopTime = Duration.ofSeconds(Units.duration(builder.hopTime)); + this.hopCost = Cost.costOfSeconds(builder.hopCost); + this.stairsReluctance = Units.reluctance(builder.stairsReluctance); + } + + public static VehicleWalkingPreferences.Builder of() { + return new VehicleWalkingPreferences.Builder(DEFAULT); + } + + public VehicleWalkingPreferences.Builder copyOf() { + return new VehicleWalkingPreferences.Builder(this); + } + + /** + * The walking speed when walking a vehicle. Default: 1.33 m/s ~ Same as walkSpeed. + */ + public double speed() { + return speed; + } + + /** + * A multiplier for how bad walking is, compared to being in transit for equal + * lengths of time. Empirically, values between 2 and 4 seem to correspond + * well to the concept of not wanting to walk too much without asking for + * totally ridiculous itineraries, but this observation should in no way be + * taken as scientific or definitive. Your mileage may vary. See + * https://github.com/opentripplanner/OpenTripPlanner/issues/4090 for impact on + * performance with high values. Default value: 2.0 + */ + public double reluctance() { + return reluctance; + } + + /** Time to get on and off your own vehicle. */ + public Duration hopTime() { + return hopTime; + } + + /** Cost of getting on and off your own vehicle. */ + public Cost hopCost() { + return hopCost; + } + + /** Reluctance of walking carrying a vehicle up a flight of stairs. */ + public double stairsReluctance() { + return stairsReluctance; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + VehicleWalkingPreferences that = (VehicleWalkingPreferences) o; + return ( + speed == that.speed && + reluctance == that.reluctance && + Objects.equals(hopTime, that.hopTime) && + Objects.equals(hopCost, that.hopCost) && + stairsReluctance == that.stairsReluctance + ); + } + + @Override + public int hashCode() { + return Objects.hash(speed, reluctance, hopTime, hopCost, stairsReluctance); + } + + @Override + public String toString() { + return ToStringBuilder + .of(VehicleWalkingPreferences.class) + .addNum("speed", speed, DEFAULT.speed) + .addNum("reluctance", reluctance, DEFAULT.reluctance) + .addObj("hopTime", hopTime, DEFAULT.hopTime) + .addObj("hopCost", hopCost, DEFAULT.hopCost) + .addNum("stairsReluctance", stairsReluctance, DEFAULT.stairsReluctance) + .toString(); + } + + public static class Builder { + + private final VehicleWalkingPreferences original; + private double speed; + private double reluctance; + private int hopTime; + private int hopCost; + private double stairsReluctance; + + private Builder(VehicleWalkingPreferences original) { + this.original = original; + this.speed = original.speed; + this.reluctance = original.reluctance; + this.hopTime = (int) original.hopTime.toSeconds(); + this.hopCost = original.hopCost.toSeconds(); + this.stairsReluctance = original.stairsReluctance; + } + + public VehicleWalkingPreferences.Builder withSpeed(double speed) { + this.speed = speed; + return this; + } + + public VehicleWalkingPreferences.Builder withReluctance(double reluctance) { + this.reluctance = reluctance; + return this; + } + + public VehicleWalkingPreferences.Builder withHopTime(Duration hopTime) { + this.hopTime = (int) hopTime.toSeconds(); + return this; + } + + public VehicleWalkingPreferences.Builder withHopTime(int hopTime) { + this.hopTime = hopTime; + return this; + } + + public VehicleWalkingPreferences.Builder withHopCost(int hopCost) { + this.hopCost = hopCost; + return this; + } + + public VehicleWalkingPreferences.Builder withStairsReluctance(double stairsReluctance) { + this.stairsReluctance = stairsReluctance; + return this; + } + + public VehicleWalkingPreferences original() { + return original; + } + + public VehicleWalkingPreferences.Builder apply( + Consumer body + ) { + body.accept(this); + return this; + } + + public VehicleWalkingPreferences build() { + var newObj = new VehicleWalkingPreferences(this); + return original.equals(newObj) ? original : newObj; + } + } +} diff --git a/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java b/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java index eb17c5d0900..799a5b006e6 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/BikeWalkableEdge.java @@ -17,8 +17,8 @@ default void switchToWalkingBike(RoutingPreferences preferences, StateEditor edi editor.setBackWalkingBike(true); if (shouldIncludeCost) { - editor.incrementWeight(preferences.bike().switchCost()); - editor.incrementTimeInSeconds(preferences.bike().switchTime()); + editor.incrementWeight(preferences.bike().walking().hopCost().toSeconds()); + editor.incrementTimeInSeconds((int) preferences.bike().walking().hopTime().toSeconds()); } } @@ -28,8 +28,8 @@ default void switchToBiking(RoutingPreferences preferences, StateEditor editor) editor.setBackWalkingBike(false); if (shouldIncludeCost) { - editor.incrementWeight(preferences.bike().switchCost()); - editor.incrementTimeInSeconds(preferences.bike().switchTime()); + editor.incrementWeight(preferences.bike().walking().hopCost().toSeconds()); + editor.incrementTimeInSeconds((int) preferences.bike().walking().hopTime().toSeconds()); } } diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java b/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java index d0b0018898a..3f17081b6cb 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java @@ -231,7 +231,9 @@ public double calculateSpeed( final double speed = switch (traverseMode) { - case WALK -> walkingBike ? preferences.bike().walkingSpeed() : preferences.walk().speed(); + case WALK -> walkingBike + ? preferences.bike().walking().speed() + : preferences.walk().speed(); case BICYCLE, SCOOTER -> preferences.bike().speed(); case CAR -> getCarSpeed(); case FLEX -> throw new IllegalArgumentException("getSpeed(): Invalid mode " + traverseMode); @@ -1276,7 +1278,7 @@ private TraversalCosts walkingTraversalCosts( time = weight = (getEffectiveBikeDistance() / speed); if (isStairs()) { // we do allow walking the bike across a stairs but there is a very high default penalty - weight *= preferences.bike().stairsReluctance(); + weight *= preferences.bike().walking().stairsReluctance(); } } else { // take slopes into account when walking diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java b/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java index 669adc2489f..ee2f3d833ee 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeReluctanceCalculator.java @@ -10,7 +10,7 @@ private StreetEdgeReluctanceCalculator() {} /** * Compute reluctance for a regular street section. Note! This does not apply if in a wheelchair, - * see {@link #computeWheelchairReluctance(RouteRequest, double, boolean, boolean)}. + * see {@link #computeWheelchairReluctance(RoutingPreferences, double, boolean, boolean)}. */ static double computeReluctance( RoutingPreferences pref, @@ -22,7 +22,7 @@ static double computeReluctance( return pref.walk().stairsReluctance(); } else { return switch (traverseMode) { - case WALK -> walkingBike ? pref.bike().walkingReluctance() : pref.walk().reluctance(); + case WALK -> walkingBike ? pref.bike().walking().reluctance() : pref.walk().reluctance(); case BICYCLE -> pref.bike().reluctance(); case CAR -> pref.car().reluctance(); default -> throw new IllegalArgumentException( diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java b/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java index 378571eeea9..a72fd25cbfa 100644 --- a/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/transmodel/mapping/preferences/BikePreferencesMapperTest.java @@ -18,7 +18,7 @@ static List mapBikePreferencesTestCases() { Arguments.of( "walkReluctance", 10.0, - "BikePreferences{reluctance: 10.0, walkingReluctance: 27.0}" + "BikePreferences{reluctance: 10.0, walking: VehicleWalkingPreferences{reluctance: 27.0}}" ), Arguments.of("bikeSpeed", 10.0, "BikePreferences{speed: 10.0}"), Arguments.of( diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java index 9da7852cc2c..9bf287737df 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java @@ -11,11 +11,7 @@ class BikePreferencesTest { public static final double SPEED = 2.0; public static final double RELUCTANCE = 1.2; - public static final double WALKING_SPEED = 1.15; public static final int BOARD_COST = 660; - public static final double WALKING_RELUCTANCE = 1.45; - public static final int SWITCH_TIME = 200; - public static final int SWITCH_COST = 450; public static final TimeSlopeSafetyTriangle TRIANGLE = TimeSlopeSafetyTriangle .of() .withSlope(1) @@ -29,10 +25,6 @@ class BikePreferencesTest { .withSpeed(SPEED) .withReluctance(RELUCTANCE) .withBoardCost(BOARD_COST) - .withWalkingSpeed(WALKING_SPEED) - .withWalkingReluctance(WALKING_RELUCTANCE) - .withSwitchTime(SWITCH_TIME) - .withSwitchCost(SWITCH_COST) .withOptimizeType(OPTIMIZE_TYPE) .withRental(rental -> rental.withPickupTime(RENTAL_PICKUP_TIME).build()) .withParking(parking -> parking.withParkCost(PARK_COST).build()) @@ -54,26 +46,6 @@ void boardCost() { assertEquals(BOARD_COST, subject.boardCost()); } - @Test - void walkingSpeed() { - assertEquals(WALKING_SPEED, subject.walkingSpeed()); - } - - @Test - void walkingReluctance() { - assertEquals(WALKING_RELUCTANCE, subject.walkingReluctance()); - } - - @Test - void switchTime() { - assertEquals(SWITCH_TIME, subject.switchTime()); - } - - @Test - void switchCost() { - assertEquals(SWITCH_COST, subject.switchCost()); - } - @Test void optimizeType() { assertEquals(OPTIMIZE_TYPE, subject.optimizeType()); diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java new file mode 100644 index 00000000000..9571eee8cc5 --- /dev/null +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferencesTest.java @@ -0,0 +1,77 @@ +package org.opentripplanner.routing.api.request.preference; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.routing.api.request.preference.ImmutablePreferencesAsserts.assertEqualsAndHashCode; + +import java.time.Duration; +import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.model.Cost; + +class VehicleWalkingPreferencesTest { + + private static final double SPEED = 1.45; + private static final double RELUCTANCE = 5.5; + private static final Duration HOP_TIME = Duration.ofSeconds(15); + private static final Cost HOP_COST = Cost.costOfSeconds(20); + private static final double STAIRS_RELUCTANCE = 11; + + private final VehicleWalkingPreferences subject = createPreferences(); + + @Test + void speed() { + assertEquals(SPEED, subject.speed()); + } + + @Test + void reluctance() { + assertEquals(RELUCTANCE, subject.reluctance()); + } + + @Test + void hopTime() { + assertEquals(HOP_TIME, subject.hopTime()); + } + + @Test + void hopCost() { + assertEquals(HOP_COST, subject.hopCost()); + } + + @Test + void stairsReluctance() { + assertEquals(STAIRS_RELUCTANCE, subject.stairsReluctance()); + } + + @Test + void testCopyOfEqualsAndHashCode() { + // Create a copy, make a change and set it back again to force creating a new object + var other = subject.copyOf().withSpeed(5.4).build(); + var same = other.copyOf().withSpeed(SPEED).build(); + assertEqualsAndHashCode(subject, other, same); + } + + @Test + void testToString() { + assertEquals("VehicleWalkingPreferences{}", VehicleWalkingPreferences.DEFAULT.toString()); + assertEquals( + "VehicleWalkingPreferences{" + + "speed: 1.45, " + + "reluctance: 5.5, " + + "hopTime: PT15S, " + + "hopCost: $20, " + + "stairsReluctance: 11.0}", + subject.toString() + ); + } + + private VehicleWalkingPreferences createPreferences() { + return VehicleWalkingPreferences + .of() + .withSpeed(SPEED) + .withReluctance(RELUCTANCE) + .withHopTime(HOP_TIME) + .withHopCost(HOP_COST.toSeconds()) + .withStairsReluctance(STAIRS_RELUCTANCE) + .build(); + } +} diff --git a/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java b/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java index e9b979e3b5b..d1ea3c8e59d 100644 --- a/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java +++ b/src/test/java/org/opentripplanner/street/integration/BarrierRoutingTest.java @@ -66,7 +66,10 @@ public void shouldWalkForBarriers() { from, to, BIKE, - rr -> rr.withPreferences(p -> p.withBike(it -> it.withWalkingReluctance(1d))), + rr -> + rr.withPreferences(p -> + p.withBike(it -> it.withWalking(walking -> walking.withReluctance(1d))) + ), itineraries -> itineraries .stream() diff --git a/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java b/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java index 66086c6d168..417f1b87347 100644 --- a/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java +++ b/src/test/java/org/opentripplanner/street/integration/BikeWalkingTest.java @@ -375,7 +375,7 @@ private List runStreetSearchAndCreateDescriptor( preferences .withWalk(w -> w.withSpeed(10)) .withBike(it -> - it.withSpeed(20d).withWalkingSpeed(5d).withSwitchTime(100).withSwitchCost(1000) + it.withSpeed(20d).withWalking(w -> w.withSpeed(5d).withHopTime(100).withHopCost(1000)) ) ); request.setArriveBy(arriveBy); diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java index 4712841a8d9..2ecfa51822a 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeCostTest.java @@ -159,7 +159,9 @@ public void bikeStairsReluctance(double stairsReluctance, long expectedCost) { .buildAndConnect(); var req = StreetSearchRequest.of(); - req.withPreferences(p -> p.withBike(b -> b.withStairsReluctance(stairsReluctance))); + req.withPreferences(p -> + p.withBike(b -> b.withWalking(w -> w.withStairsReluctance(stairsReluctance))) + ); req.withMode(StreetMode.BIKE); var result = traverse(stairsEdge, req.build()); assertEquals(expectedCost, (long) result.weight); diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java index e131bae1a7a..42d841b9fa3 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetEdgeTest.java @@ -55,7 +55,9 @@ public void before() { references .withStreet(s -> s.withTurnReluctance(1.0)) .withWalk(it -> it.withSpeed(1.0).withReluctance(1.0).withStairsReluctance(1.0)) - .withBike(it -> it.withSpeed(5.0f).withReluctance(1.0).withWalkingSpeed(0.8)) + .withBike(it -> + it.withSpeed(5.0f).withReluctance(1.0).withWalking(w -> w.withSpeed(0.8)) + ) .withCar(c -> c.withSpeed(15.0f).withReluctance(1.0)) ) .build(); @@ -218,7 +220,9 @@ public void testBikeSwitch() { StreetEdge e2 = streetEdge(v2, v0, 0.0, StreetTraversalPermission.PEDESTRIAN_AND_BICYCLE); StreetSearchRequestBuilder noPenalty = StreetSearchRequest.copyOf(proto); - noPenalty.withPreferences(p -> p.withBike(it -> it.withSwitchTime(0).withSwitchCost(0))); + noPenalty.withPreferences(p -> + p.withBike(it -> it.withWalking(w -> w.withHopTime(0).withHopCost(0))) + ); State s0 = new State(v0, noPenalty.withMode(StreetMode.BIKE).build()); State s1 = e0.traverse(s0)[0]; @@ -226,7 +230,9 @@ public void testBikeSwitch() { State s3 = e2.traverse(s2)[0]; StreetSearchRequestBuilder withPenalty = StreetSearchRequest.copyOf(proto); - withPenalty.withPreferences(p -> p.withBike(it -> it.withSwitchTime(42).withSwitchCost(23))); + withPenalty.withPreferences(p -> + p.withBike(it -> it.withWalking(w -> w.withHopTime(42).withHopCost(23))) + ); State s4 = new State(v0, withPenalty.withMode(StreetMode.BIKE).build()); State s5 = e0.traverse(s4)[0]; From f96c42bd52b4f22a1778d6baea3e4bfb0faab03a Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 18 Dec 2023 17:30:48 +0200 Subject: [PATCH 02/21] Restructure and name bike/car preferences in router-config --- docs/RouteRequest.md | 290 +++++++++++------- docs/RouterConfiguration.md | 45 ++- docs/examples/entur/router-config.json | 45 ++- docs/examples/ibi/atlanta/router-config.json | 24 +- .../routerequest/RouteRequestConfig.java | 272 +++------------- .../TriangleOptimizationConfig.java | 53 ++++ .../routerequest/VehicleParkingConfig.java | 93 ++++++ .../routerequest/VehicleRentalConfig.java | 8 +- .../routerequest/VehicleWalkingConfig.java | 82 +++++ .../standalone/config/router-config.json | 45 ++- .../performance/norway/speed-test-config.json | 6 +- .../switzerland/speed-test-config.json | 6 +- 12 files changed, 556 insertions(+), 413 deletions(-) create mode 100644 src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java create mode 100644 src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java create mode 100644 src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 9e891cf732d..755f5f73e28 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -17,29 +17,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |--------------------------------------------------------------------------------------------------------------|:----------------------:|------------------------------------------------------------------------------------------------------------------------------------------------|:----------:|------------------|:-----:| | [alightSlack](#rd_alightSlack) | `duration` | The minimum extra time after exiting a public transport vehicle. | *Optional* | `"PT0S"` | 2.0 | | arriveBy | `boolean` | Whether the trip should depart or arrive at the specified date and time. | *Optional* | `false` | 2.0 | -| [bikeBoardCost](#rd_bikeBoardCost) | `integer` | Prevents unnecessary transfers by adding a cost for boarding a vehicle. | *Optional* | `600` | 2.0 | -| bikeParkCost | `integer` | Cost to park a bike. | *Optional* | `120` | 2.0 | -| bikeParkTime | `duration` | Time to park a bike. | *Optional* | `"PT1M"` | 2.0 | -| bikeReluctance | `double` | A multiplier for how bad biking is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | -| bikeSpeed | `double` | Max bike speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | -| bikeStairsReluctance | `double` | How bad is it to walk the bicycle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | -| bikeSwitchCost | `integer` | The cost of the user fetching their bike and parking it again. | *Optional* | `0` | 2.0 | -| bikeSwitchTime | `integer` | The time it takes the user to fetch their bike and park it again in seconds. | *Optional* | `0` | 2.0 | -| bikeTriangleSafetyFactor | `double` | For bike triangle routing, how much safety matters (range 0-1). | *Optional* | `0.0` | 2.0 | -| bikeTriangleSlopeFactor | `double` | For bike triangle routing, how much slope matters (range 0-1). | *Optional* | `0.0` | 2.0 | -| bikeTriangleTimeFactor | `double` | For bike triangle routing, how much time matters (range 0-1). | *Optional* | `0.0` | 2.0 | -| bikeWalkingReluctance | `double` | A multiplier for how bad walking with a bike is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | -| bikeWalkingSpeed | `double` | The user's bike walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | | [boardSlack](#rd_boardSlack) | `duration` | The boardSlack is the minimum extra time to board a public transport vehicle. | *Optional* | `"PT0S"` | 2.0 | -| carAccelerationSpeed | `double` | The acceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | -| carDecelerationSpeed | `double` | The deceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | -| carDropoffTime | `integer` | Time to park a car in a park and ride, w/o taking into account driving and walking cost. | *Optional* | `120` | 2.0 | -| carParkCost | `integer` | Cost of parking a car. | *Optional* | `120` | 2.1 | -| carParkTime | `duration` | Time to park a car | *Optional* | `"PT1M"` | 2.1 | -| carPickupCost | `integer` | Add a cost for car pickup changes when a pickup or drop off takes place | *Optional* | `120` | 2.1 | -| carPickupTime | `integer` | Add a time for car pickup changes when a pickup or drop off takes place | *Optional* | `60` | 2.1 | -| carReluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | -| carSpeed | `double` | Max car speed along streets, in meters per second | *Optional* | `40.0` | 2.0 | | [drivingDirection](#rd_drivingDirection) | `enum` | The driving direction to use in the intersection traversal calculation | *Optional* | `"right"` | 2.2 | | elevatorBoardCost | `integer` | What is the cost of boarding a elevator? | *Optional* | `90` | 2.0 | | elevatorBoardTime | `integer` | How long does it take to get on an elevator, on average. | *Optional* | `90` | 2.0 | @@ -55,7 +33,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | modes | `string` | The set of access/egress/direct/transit modes to be used for the route search. | *Optional* | `"TRANSIT,WALK"` | 2.0 | | nonpreferredTransferPenalty | `integer` | Penalty (in seconds) for using a non-preferred transfer. | *Optional* | `180` | 2.0 | | numItineraries | `integer` | The maximum number of itineraries to return. | *Optional* | `50` | 2.0 | -| [optimize](#rd_optimize) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe"` | 2.0 | | [otherThanPreferredRoutesPenalty](#rd_otherThanPreferredRoutesPenalty) | `integer` | Penalty added for using every route that is not preferred if user set any route as preferred. | *Optional* | `300` | 2.0 | | [relaxTransitPriorityGroup](#rd_relaxTransitPriorityGroup) | `string` | The relax function for transit-priority-groups | *Optional* | `"0s + 1.00 t"` | 2.5 | | [relaxTransitSearchGeneralizedCostAtDestination](#rd_relaxTransitSearchGeneralizedCostAtDestination) | `double` | Whether non-optimal transit paths at the destination should be returned | *Optional* | | 2.3 | @@ -67,7 +44,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | [transferSlack](#rd_transferSlack) | `integer` | The extra time needed to make a safe transfer in seconds. | *Optional* | `120` | 2.0 | | turnReluctance | `double` | Multiplicative factor on expected turning time. | *Optional* | `1.0` | 2.0 | | [unpreferredCost](#rd_unpreferredCost) | `cost-linear-function` | A cost function used to calculate penalty for an unpreferred route. | *Optional* | `"0s + 1.00 t"` | 2.2 | -| [unpreferredVehicleParkingTagCost](#rd_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | | waitReluctance | `double` | How much worse is waiting for a transit vehicle than being on a transit vehicle, as a multiplier. | *Optional* | `1.0` | 2.0 | | walkBoardCost | `integer` | Prevents unnecessary transfers by adding a cost for boarding a vehicle. This is the cost that is used when boarding while walking. | *Optional* | `600` | 2.0 | | [walkReluctance](#rd_walkReluctance) | `double` | A multiplier for how bad walking is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | @@ -82,8 +58,55 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |          costFactor | `double` | A factor multiplied with the time-penalty to get the cost-penalty. | *Optional* | `0.0` | 2.4 | |          timePenalty | `time-penalty` | Penalty added to the time of a path/leg. | *Optional* | `"0s + 0.00 t"` | 2.4 | | [alightSlackForMode](#rd_alightSlackForMode) | `enum map of duration` | How much extra time should be given when alighting a vehicle for each given mode. | *Optional* | | 2.0 | -| [bannedVehicleParkingTags](#rd_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | +| bicycle | `object` | Bicycle preferences. | *Optional* | | 2.5 | +|    [boardCost](#rd_bicycle_boardCost) | `integer` | Prevents unnecessary transfers by adding a cost for boarding a transit vehicle. | *Optional* | `600` | 2.0 | +|    [optimization](#rd_bicycle_optimization) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe"` | 2.0 | +|    reluctance | `double` | A multiplier for how bad cycling is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | +|    speed | `double` | Max bicycle speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | +|    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | +|       parkCost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | +|       parkTime | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       [unpreferredVehicleParkingTagCost](#rd_bicycle_parking_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | +|       [bannedVehicleParkingTags](#rd_bicycle_parking_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | +|       [preferredVehicleParkingTags](#rd_bicycle_parking_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | +|       [requiredVehicleParkingTags](#rd_bicycle_parking_requiredVehicleParkingTags) | `string[]` | Tags without which a vehicle parking will not be used. If empty, no tags are required. | *Optional* | | 2.1 | +|    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | +|       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | +|       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | +|       dropOffTime | `integer` | Time to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | +|       keepingAtDestinationCost | `double` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0.0` | 2.2 | +|       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | +|       pickupTime | `integer` | Time to rent a vehicle. | *Optional* | `60` | 2.0 | +|       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | +|       [allowedNetworks](#rd_bicycle_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | +|       [bannedNetworks](#rd_bicycle_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | +|    triangle | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | +|    walking | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | +|       [hopCost](#rd_bicycle_walking_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | +|       [hopTime](#rd_bicycle_walking_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle in seconds. | *Optional* | `"PT0S"` | 2.0 | +|       reluctance | `double` | A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | +|       speed | `double` | The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | +|       stairsReluctance | `double` | How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | | [boardSlackForMode](#rd_boardSlackForMode) | `enum map of duration` | How much extra time should be given when boarding a vehicle for each given mode. | *Optional* | | 2.0 | +| car | `object` | Car preferences. | *Optional* | | 2.5 | +|    accelerationSpeed | `double` | The acceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | +|    decelerationSpeed | `double` | The deceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | +|    dropoffTime | `integer` | Time to park a car in a park and ride, w/o taking into account driving and walking cost. | *Optional* | `120` | 2.0 | +|    pickupCost | `integer` | Add a cost for car pickup changes when a pickup or drop off takes place | *Optional* | `120` | 2.1 | +|    pickupTime | `integer` | Add a time for car pickup changes when a pickup or drop off takes place | *Optional* | `60` | 2.1 | +|    reluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | +|    speed | `double` | Max car speed along streets, in meters per second | *Optional* | `40.0` | 2.0 | +|    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | +|    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | +|       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | +|       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | +|       dropOffTime | `integer` | Time to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | +|       keepingAtDestinationCost | `double` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0.0` | 2.2 | +|       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | +|       pickupTime | `integer` | Time to rent a vehicle. | *Optional* | `60` | 2.0 | +|       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | +|       [allowedNetworks](#rd_car_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | +|       [bannedNetworks](#rd_car_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | | [itineraryFilters](#rd_itineraryFilters) | `object` | Configure itinerary filters that may modify itineraries, sort them, and filter away less preferable results. | *Optional* | | 2.0 | |    [accessibilityScore](#rd_if_accessibilityScore) | `boolean` | An experimental feature contributed by IBI which adds a sandbox accessibility *score* between 0 and 1 for each leg and itinerary. | *Optional* | `false` | 2.2 | |    [bikeRentalDistanceRatio](#rd_if_bikeRentalDistanceRatio) | `double` | Filter routes that consist of bike-rental and walking by the minimum fraction of the bike-rental leg using _distance_. | *Optional* | `0.0` | 2.1 | @@ -101,8 +124,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       [costLimitFunction](#rd_if_transitGeneralizedCostLimit_costLimitFunction) | `cost-linear-function` | The base function used by the filter. | *Optional* | `"15m + 1.50 t"` | 2.2 | |       [intervalRelaxFactor](#rd_if_transitGeneralizedCostLimit_intervalRelaxFactor) | `double` | How much the filter should be relaxed for itineraries that do not overlap in time. | *Optional* | `0.4` | 2.2 | | [maxDirectStreetDurationForMode](#rd_maxDirectStreetDurationForMode) | `enum map of duration` | Limit direct route duration per street mode. | *Optional* | | 2.2 | -| [preferredVehicleParkingTags](#rd_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | -| [requiredVehicleParkingTags](#rd_requiredVehicleParkingTags) | `string[]` | Tags without which a vehicle parking will not be used. If empty, no tags are required. | *Optional* | | 2.1 | | [transferOptimization](#rd_transferOptimization) | `object` | Optimize where a transfer between to trip happens. | *Optional* | | 2.1 | |    [backTravelWaitTimeFactor](#rd_to_backTravelWaitTimeFactor) | `double` | To reduce back-travel we favor waiting, this reduces the cost of waiting. | *Optional* | `1.0` | 2.1 | |    [extraStopBoardAlightCostsFactor](#rd_to_extraStopBoardAlightCostsFactor) | `double` | Add an extra board- and alight-cost for prioritized stops. | *Optional* | `0.0` | 2.1 | @@ -113,16 +134,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | [unpreferred](#rd_unpreferred) | `object` | Parameters listing authorities or lines that preferably should not be used in trip patters. | *Optional* | | 2.2 | |    [agencies](#rd_unpreferred_agencies) | `feed-scoped-id[]` | The ids of the agencies that incur an extra cost when being used. Format: `FeedId:AgencyId` | *Optional* | | 2.2 | |    [routes](#rd_unpreferred_routes) | `feed-scoped-id[]` | The ids of the routes that incur an extra cost when being used. Format: `FeedId:RouteId` | *Optional* | | 2.2 | -| vehicleRental | `object` | Vehicle rental options | *Optional* | | 2.3 | -|    allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | -|    dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|    dropOffTime | `integer` | Time to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|    keepingAtDestinationCost | `double` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0.0` | 2.2 | -|    pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | -|    pickupTime | `integer` | Time to rent a vehicle. | *Optional* | `60` | 2.0 | -|    useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | -|    [allowedNetworks](#rd_vehicleRental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | -|    [bannedNetworks](#rd_vehicleRental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | | wheelchairAccessibility | `object` | See [Wheelchair Accessibility](Accessibility.md) | *Optional* | | 2.2 | |    enabled | `boolean` | Enable wheelchair accessibility. | *Optional* | `false` | 2.0 | |    inaccessibleStreetReluctance | `double` | The factor to multiply the cost of traversing a street edge that is not wheelchair-accessible. | *Optional* | `25.0` | 2.2 | @@ -159,15 +170,6 @@ The minimum extra time after exiting a public transport vehicle. The slack is added to the time when going from the transit vehicle to the stop. -

bikeBoardCost

- -**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `600` -**Path:** /routingDefaults - -Prevents unnecessary transfers by adding a cost for boarding a vehicle. - -This is the cost that is used when boarding while cycling.This is usually higher that walkBoardCost. -

boardSlack

**Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` @@ -230,14 +232,6 @@ search, hence, making it a bit slower. Recommended values would be from 12 hours 1 day (region) to 2 days (country like Norway)." -

optimize

- -**Since version:** `2.0` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"safe"` -**Path:** /routingDefaults -**Enum values:** `quick` | `safe` | `flat` | `greenways` | `triangle` - -The set of characteristics that the user wants to optimize for. -

otherThanPreferredRoutesPenalty

**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `300` @@ -364,15 +358,6 @@ Function should return number of seconds that we are willing to wait for preferr or for an unpreferred agency's departure. For example: `5m + 2.0 t` -

unpreferredVehicleParkingTagCost

- -**Since version:** `2.3` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `300` -**Path:** /routingDefaults - -What cost to add if a parking facility doesn't contain a preferred tag. - -See `preferredVehicleParkingTags`. -

walkReluctance

**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `2.0` @@ -473,16 +458,98 @@ How much extra time should be given when alighting a vehicle for each given mode Sometimes there is a need to configure a longer alighting times for specific modes, such as airplanes or ferries. -

bannedVehicleParkingTags

+

boardCost

+ +**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `600` +**Path:** /routingDefaults/bicycle + +Prevents unnecessary transfers by adding a cost for boarding a transit vehicle. + +This is the cost that is used when boarding while cycling.This is usually higher that walkBoardCost. + +

optimization

+ +**Since version:** `2.0` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"safe"` +**Path:** /routingDefaults/bicycle +**Enum values:** `quick` | `safe` | `flat` | `greenways` | `triangle` + +The set of characteristics that the user wants to optimize for. + +

unpreferredVehicleParkingTagCost

+ +**Since version:** `2.3` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `300` +**Path:** /routingDefaults/bicycle/parking + +What cost to add if a parking facility doesn't contain a preferred tag. + +See `preferredVehicleParkingTags`. + +

bannedVehicleParkingTags

**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` -**Path:** /routingDefaults +**Path:** /routingDefaults/bicycle/parking Tags with which a vehicle parking will not be used. If empty, no tags are banned. Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). +

preferredVehicleParkingTags

+ +**Since version:** `2.3` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/bicycle/parking + +Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. + +Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + + +

requiredVehicleParkingTags

+ +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/bicycle/parking + +Tags without which a vehicle parking will not be used. If empty, no tags are required. + +Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + + +

allowedNetworks

+ +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/bicycle/rental + +The vehicle rental networks which may be used. If empty all networks may be used. + +

bannedNetworks

+ +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/bicycle/rental + +The vehicle rental networks which may not be used. If empty, no networks are banned. + +

hopCost

+ +**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0` +**Path:** /routingDefaults/bicycle/walking + +The cost of hopping on or off a vehicle. + +There are different parameters for the cost of renting or parking a vehicle and this is +not meant for controlling the cost of those events. + + +

hopTime

+ +**Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` +**Path:** /routingDefaults/bicycle/walking + +The time it takes the user to hop on or off a vehicle in seconds. + +Time it takes to rent or park a vehicle have their own parameters and this is not meant +for controlling the duration of those events. + +

boardSlackForMode

**Since version:** `2.0` ∙ **Type:** `enum map of duration` ∙ **Cardinality:** `Optional` @@ -495,6 +562,20 @@ Sometimes there is a need to configure a board times for specific modes, such as ferries, where the check-in process needs to be done in good time before ride. +

allowedNetworks

+ +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/car/rental + +The vehicle rental networks which may be used. If empty all networks may be used. + +

bannedNetworks

+ +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/car/rental + +The vehicle rental networks which may not be used. If empty, no networks are banned. +

itineraryFilters

**Since version:** `2.0` ∙ **Type:** `object` ∙ **Cardinality:** `Optional` @@ -710,26 +791,6 @@ Override the settings in `maxDirectStreetDuration` for specific street modes. Th done because some street modes searches are much more resource intensive than others. -

preferredVehicleParkingTags

- -**Since version:** `2.3` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` -**Path:** /routingDefaults - -Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. - -Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - - -

requiredVehicleParkingTags

- -**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` -**Path:** /routingDefaults - -Tags without which a vehicle parking will not be used. If empty, no tags are required. - -Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - -

transferOptimization

**Since version:** `2.1` ∙ **Type:** `object` ∙ **Cardinality:** `Optional` @@ -873,20 +934,6 @@ The ids of the routes that incur an extra cost when being used. Format: `FeedId: How much cost is added is configured in `unpreferredCost`. -

allowedNetworks

- -**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` -**Path:** /routingDefaults/vehicleRental - -The vehicle rental networks which may be used. If empty all networks may be used. - -

bannedNetworks

- -**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` -**Path:** /routingDefaults/vehicleRental - -The vehicle rental networks which may not be used. If empty, no networks are banned. -

maxSlope

**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.083` @@ -934,15 +981,9 @@ include stairs as a last result. { "routingDefaults" : { "walkSpeed" : 1.3, - "bikeSpeed" : 5, - "carSpeed" : 40, "numItineraries" : 12, "transferPenalty" : 0, "walkReluctance" : 4.0, - "bikeReluctance" : 5.0, - "bikeWalkingReluctance" : 10.0, - "bikeStairsReluctance" : 150.0, - "carReluctance" : 10.0, "stairsReluctance" : 1.65, "turnReluctance" : 1.0, "elevatorBoardTime" : 90, @@ -950,17 +991,38 @@ include stairs as a last result. "elevatorHopTime" : 20, "elevatorHopCost" : 20, "escalatorReluctance" : 1.5, - "vehicleRental" : { - "pickupCost" : 120, - "dropOffTime" : 30, - "dropOffCost" : 30 + "bicycle" : { + "speed" : 5, + "reluctance" : 5.0, + "boardCost" : 600, + "walking" : { + "reluctance" : 10.0, + "stairsReluctance" : 150.0 + }, + "rental" : { + "pickupCost" : 120, + "dropOffTime" : 30, + "dropOffCost" : 30 + }, + "parking" : { + "parkTime" : "1m", + "parkCost" : 120 + } + }, + "car" : { + "speed" : 40, + "reluctance" : 10, + "dropoffTime" : 120, + "decelerationSpeed" : 2.9, + "accelerationSpeed" : 2.9, + "rental" : { + "pickupCost" : 120, + "dropOffTime" : 30, + "dropOffCost" : 30 + } }, - "bikeParkTime" : "1m", - "bikeParkCost" : 120, - "carDropoffTime" : 120, "waitReluctance" : 1.0, "walkBoardCost" : 600, - "bikeBoardCost" : 600, "otherThanPreferredRoutesPenalty" : 300, "transferSlack" : 120, "boardSlackForMode" : { @@ -997,8 +1059,6 @@ include stairs as a last result. "minBikeParkingDistance" : 300, "debug" : "limit-to-search-window" }, - "carDecelerationSpeed" : 2.9, - "carAccelerationSpeed" : 2.9, "ignoreRealtimeUpdates" : false, "geoidElevation" : false, "maxJourneyDuration" : "36h", diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 65f50260ee5..37a673ea7a2 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -452,15 +452,9 @@ Used to group requests when monitoring OTP. }, "routingDefaults" : { "walkSpeed" : 1.3, - "bikeSpeed" : 5, - "carSpeed" : 40, "numItineraries" : 12, "transferPenalty" : 0, "walkReluctance" : 4.0, - "bikeReluctance" : 5.0, - "bikeWalkingReluctance" : 10.0, - "bikeStairsReluctance" : 150.0, - "carReluctance" : 10.0, "stairsReluctance" : 1.65, "turnReluctance" : 1.0, "elevatorBoardTime" : 90, @@ -468,17 +462,38 @@ Used to group requests when monitoring OTP. "elevatorHopTime" : 20, "elevatorHopCost" : 20, "escalatorReluctance" : 1.5, - "vehicleRental" : { - "pickupCost" : 120, - "dropOffTime" : 30, - "dropOffCost" : 30 + "bicycle" : { + "speed" : 5, + "reluctance" : 5.0, + "boardCost" : 600, + "walking" : { + "reluctance" : 10.0, + "stairsReluctance" : 150.0 + }, + "rental" : { + "pickupCost" : 120, + "dropOffTime" : 30, + "dropOffCost" : 30 + }, + "parking" : { + "parkTime" : "1m", + "parkCost" : 120 + } + }, + "car" : { + "speed" : 40, + "reluctance" : 10, + "dropoffTime" : 120, + "decelerationSpeed" : 2.9, + "accelerationSpeed" : 2.9, + "rental" : { + "pickupCost" : 120, + "dropOffTime" : 30, + "dropOffCost" : 30 + } }, - "bikeParkTime" : "1m", - "bikeParkCost" : 120, - "carDropoffTime" : 120, "waitReluctance" : 1.0, "walkBoardCost" : 600, - "bikeBoardCost" : 600, "otherThanPreferredRoutesPenalty" : 300, "transferSlack" : 120, "boardSlackForMode" : { @@ -515,8 +530,6 @@ Used to group requests when monitoring OTP. "minBikeParkingDistance" : 300, "debug" : "limit-to-search-window" }, - "carDecelerationSpeed" : 2.9, - "carAccelerationSpeed" : 2.9, "ignoreRealtimeUpdates" : false, "geoidElevation" : false, "maxJourneyDuration" : "36h", diff --git a/docs/examples/entur/router-config.json b/docs/examples/entur/router-config.json index 0023dab130a..2d217cb2402 100644 --- a/docs/examples/entur/router-config.json +++ b/docs/examples/entur/router-config.json @@ -2,31 +2,46 @@ "configVersion" : "{{ Entur CI config build number inserted here }}", "routingDefaults": { "walkSpeed": 1.3, - "bikeSpeed": 5, - "carSpeed": 40, "numItineraries": 12, "transferPenalty": 0, "walkReluctance": 4.0, - "bikeReluctance": 5.0, - "bikeWalkingReluctance": 10.0, - "carReluctance": 10.0, "stairsReluctance": 1.65, "turnReluctance": 1.0, "elevatorBoardTime": 90, "elevatorBoardCost": 90, "elevatorHopTime": 20, "elevatorHopCost": 20, - "vehicleRental": { - "pickupCost": 120, - "dropOffTime": 30, - "dropOffCost": 30 + "bicycle": { + "speed": 5, + "reluctance": 5.0, + "boardCost": 600, + "walking": { + "reluctance": 10.0 + }, + "rental": { + "pickupCost": 120, + "dropOffTime": 30, + "dropOffCost": 30 + }, + "parking": { + "parkTime": "1m", + "parkCost": 120 + } + }, + "car": { + "speed": 40, + "reluctance": 4.0, + "dropoffTime": 120, + "decelerationSpeed": 2.9, + "accelerationSpeed": 2.9, + "rental": { + "pickupCost": 120, + "dropOffTime": 30, + "dropOffCost": 30 + } }, - "bikeParkTime": "1m", - "bikeParkCost": 120, - "carDropoffTime": 120, "waitReluctance": 1.0, "walkBoardCost": 600, - "bikeBoardCost": 600, "otherThanPreferredRoutesPenalty": 300, "transferSlack": 120, // Default slack for any mode is 0 (zero) @@ -41,15 +56,13 @@ }, "accessEgress": { "maxDurationForMode": { - "BIKE_RENTAL": "20m" + "BIKE_RENTAL": "20m" } }, "itineraryFilters" : { "transitGeneralizedCostLimit" : "1h + 2.5 x", "bikeRentalDistanceRatio": 0.3 }, - "carDecelerationSpeed": 2.9, - "carAccelerationSpeed": 2.9, "ignoreRealtimeUpdates": false, "geoidElevation": false, "maxJourneyDuration": "36h", diff --git a/docs/examples/ibi/atlanta/router-config.json b/docs/examples/ibi/atlanta/router-config.json index 5202fe227c1..2aeb3e6434e 100644 --- a/docs/examples/ibi/atlanta/router-config.json +++ b/docs/examples/ibi/atlanta/router-config.json @@ -1,18 +1,28 @@ { "routingDefaults": { - "bikeTriangleSafetyFactor": 0.4, - "bikeTriangleSlopeFactor": 0.3, - "bikeTriangleTimeFactor": 0.3, + "bicycle": { + "triangle": { + "time": 0.3, + "flatness": 0.3, + "safety": 0.4 + }, + "rental": { + "pickupTime": 180, + "pickupCost": 850 + } + }, + "car": { + "rental": { + "pickupTime": 180, + "pickupCost": 850 + } + }, "itineraryFilters": { // only show non-transit (ie. walking) when it's at least as good as the transit option "nonTransitGeneralizedCostLimit": "0 + 1.0 x", // add IBI accessibility score between 0 and 1 "accessibilityScore": true }, - "vehicleRental": { - "pickupTime": 180, - "pickupCost": 850 - }, // use stop and trip with unknown wheelchair accessibility during routing "wheelchairAccessibility": { "trip": { diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index e600f1f8f12..0ff1c48cf2b 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -8,11 +8,13 @@ import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; import static org.opentripplanner.standalone.config.routerequest.ItineraryFiltersConfig.mapItineraryFilterParams; import static org.opentripplanner.standalone.config.routerequest.TransferConfig.mapTransferPreferences; -import static org.opentripplanner.standalone.config.routerequest.VehicleRentalConfig.setVehicleRental; +import static org.opentripplanner.standalone.config.routerequest.TriangleOptimizationConfig.mapOptimizationTriangle; +import static org.opentripplanner.standalone.config.routerequest.VehicleParkingConfig.mapParking; +import static org.opentripplanner.standalone.config.routerequest.VehicleRentalConfig.mapRental; +import static org.opentripplanner.standalone.config.routerequest.VehicleWalkingConfig.mapVehicleWalking; import static org.opentripplanner.standalone.config.routerequest.WheelchairConfig.mapWheelchairPreferences; import java.time.Duration; -import java.util.List; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.routing.api.request.RequestModes; @@ -25,7 +27,6 @@ import org.opentripplanner.routing.api.request.preference.StreetPreferences; import org.opentripplanner.routing.api.request.preference.SystemPreferences; import org.opentripplanner.routing.api.request.preference.TransitPreferences; -import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; import org.opentripplanner.routing.api.request.preference.WalkPreferences; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; import org.opentripplanner.standalone.config.sandbox.DataOverlayParametersMapper; @@ -335,176 +336,48 @@ The board time is added to the time when going from the stop (offboard) to onboa private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder builder) { var dft = builder.original(); + NodeAdapter cb = c.of("bicycle").since(V2_5).summary("Bicycle preferences.").asObject(); builder .withSpeed( - c - .of("bikeSpeed") + cb + .of("speed") .since(V2_0) - .summary("Max bike speed along streets, in meters per second") + .summary("Max bicycle speed along streets, in meters per second") .asDouble(dft.speed()) ) .withReluctance( - c - .of("bikeReluctance") + cb + .of("reluctance") .since(V2_0) .summary( - "A multiplier for how bad biking is, compared to being in transit for equal lengths of time." + "A multiplier for how bad cycling is, compared to being in transit for equal lengths of time." ) .asDouble(dft.reluctance()) ) .withBoardCost( - c - .of("bikeBoardCost") + cb + .of("boardCost") .since(V2_0) - .summary("Prevents unnecessary transfers by adding a cost for boarding a vehicle.") + .summary( + "Prevents unnecessary transfers by adding a cost for boarding a transit vehicle." + ) .description( "This is the cost that is used when boarding while cycling." + "This is usually higher that walkBoardCost." ) .asInt(dft.boardCost()) ) - .withWalkingSpeed( - c - .of("bikeWalkingSpeed") - .since(V2_1) - .summary( - "The user's bike walking speed in meters/second. Defaults to approximately 3 MPH." - ) - .asDouble(dft.walkingSpeed()) - ) - .withWalkingReluctance( - c - .of("bikeWalkingReluctance") - .since(V2_1) - .summary( - "A multiplier for how bad walking with a bike is, compared to being in transit for equal lengths of time." - ) - .asDouble(dft.walkingReluctance()) - ) - .withSwitchTime( - c - .of("bikeSwitchTime") - .since(V2_0) - .summary("The time it takes the user to fetch their bike and park it again in seconds.") - .asInt(dft.switchTime()) - ) - .withSwitchCost( - c - .of("bikeSwitchCost") - .since(V2_0) - .summary("The cost of the user fetching their bike and parking it again.") - .asInt(dft.switchCost()) - ) .withOptimizeType( - c - .of("optimize") + cb + .of("optimization") .since(V2_0) .summary("The set of characteristics that the user wants to optimize for.") .asEnum(dft.optimizeType()) ) - .withOptimizeTriangle(it -> - it - .withTime( - c - .of("bikeTriangleTimeFactor") - .since(V2_0) - .summary("For bike triangle routing, how much time matters (range 0-1).") - .asDouble(it.time()) - ) - .withSlope( - c - .of("bikeTriangleSlopeFactor") - .since(V2_0) - .summary("For bike triangle routing, how much slope matters (range 0-1).") - .asDouble(it.slope()) - ) - .withSafety( - c - .of("bikeTriangleSafetyFactor") - .since(V2_0) - .summary("For bike triangle routing, how much safety matters (range 0-1).") - .asDouble(it.safety()) - ) - ) - .withStairsReluctance( - c - .of("bikeStairsReluctance") - .since(V2_3) - .summary( - "How bad is it to walk the bicycle up/down a flight of stairs compared to taking a detour." - ) - .asDouble(dft.stairsReluctance()) - ) - .withParking(it -> - it - .withUnpreferredVehicleParkingTagCost( - c - .of("unpreferredVehicleParkingTagCost") - .since(V2_3) - .summary("What cost to add if a parking facility doesn't contain a preferred tag.") - .description("See `preferredVehicleParkingTags`.") - .asInt( - VehicleParkingPreferences.DEFAULT.unpreferredVehicleParkingTagCost().toSeconds() - ) - ) - .withBannedVehicleParkingTags( - c - .of("bannedVehicleParkingTags") - .since(V2_1) - .summary( - "Tags with which a vehicle parking will not be used. If empty, no tags are banned." - ) - .description( - """ - Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - """ - ) - .asStringSet(List.of()) - ) - .withRequiredVehicleParkingTags( - c - .of("requiredVehicleParkingTags") - .since(V2_1) - .summary( - "Tags without which a vehicle parking will not be used. If empty, no tags are required." - ) - .description( - """ - Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - """ - ) - .asStringSet(List.of()) - ) - .withParkTime( - c - .of("bikeParkTime") - .since(V2_0) - .summary("Time to park a bike.") - .asDuration(VehicleParkingPreferences.DEFAULT.parkTime()) - ) - .withParkCost( - c - .of("bikeParkCost") - .since(V2_0) - .summary("Cost to park a bike.") - .asInt(VehicleParkingPreferences.DEFAULT.parkCost().toSeconds()) - ) - .withPreferredVehicleParkingTags( - c - .of("preferredVehicleParkingTags") - .since(V2_3) - .summary( - "Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised." - ) - .description( - """ - Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - """ - ) - .asStringSet(List.of()) - ) - ) - .withRental(it -> setVehicleRental(c, it)); + .withOptimizeTriangle(it -> mapOptimizationTriangle(cb, it)) + .withWalking(it -> mapVehicleWalking(cb, it)) + .withParking(it -> mapParking(cb, it)) + .withRental(it -> mapRental(cb, it)); } private static void mapStreetPreferences(NodeAdapter c, StreetPreferences.Builder builder) { @@ -695,17 +568,18 @@ The street search(AStar) aborts after this duration and any paths found are retu private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder builder) { var dft = builder.original(); + NodeAdapter cc = c.of("car").since(V2_5).summary("Car preferences.").asObject(); builder .withSpeed( - c - .of("carSpeed") + cc + .of("speed") .since(V2_0) .summary("Max car speed along streets, in meters per second") .asDouble(dft.speed()) ) .withReluctance( - c - .of("carReluctance") + cc + .of("reluctance") .since(V2_0) .summary( "A multiplier for how bad driving is, compared to being in transit for equal lengths of time." @@ -713,8 +587,8 @@ private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder buil .asDouble(dft.reluctance()) ) .withDropoffTime( - c - .of("carDropoffTime") + cc + .of("dropoffTime") .since(V2_0) .summary( "Time to park a car in a park and ride, w/o taking into account driving and walking cost." @@ -722,103 +596,35 @@ private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder buil .asInt(dft.dropoffTime()) ) .withPickupCost( - c - .of("carPickupCost") + cc + .of("pickupCost") .since(V2_1) .summary("Add a cost for car pickup changes when a pickup or drop off takes place") .asInt(dft.pickupCost()) ) .withPickupTime( - c - .of("carPickupTime") + cc + .of("pickupTime") .since(V2_1) .summary("Add a time for car pickup changes when a pickup or drop off takes place") .asInt(dft.pickupTime()) ) .withAccelerationSpeed( - c - .of("carAccelerationSpeed") + cc + .of("accelerationSpeed") .since(V2_0) .summary("The acceleration speed of an automobile, in meters per second per second.") .asDouble(dft.accelerationSpeed()) ) .withDecelerationSpeed( - c - .of("carDecelerationSpeed") + cc + .of("decelerationSpeed") .since(V2_0) .summary("The deceleration speed of an automobile, in meters per second per second.") .asDouble(dft.decelerationSpeed()) ) - .withParking(it -> - it - .withUnpreferredVehicleParkingTagCost( - c - .of("unpreferredVehicleParkingTagCost") - .since(V2_3) - .summary("What cost to add if a parking facility doesn't contain a preferred tag.") - .description("See `preferredVehicleParkingTags`.") - .asInt( - VehicleParkingPreferences.DEFAULT.unpreferredVehicleParkingTagCost().toSeconds() - ) - ) - .withBannedVehicleParkingTags( - c - .of("bannedVehicleParkingTags") - .since(V2_1) - .summary( - "Tags with which a vehicle parking will not be used. If empty, no tags are banned." - ) - .description( - """ - Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - """ - ) - .asStringSet(List.of()) - ) - .withRequiredVehicleParkingTags( - c - .of("requiredVehicleParkingTags") - .since(V2_1) - .summary( - "Tags without which a vehicle parking will not be used. If empty, no tags are required." - ) - .description( - """ - Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - """ - ) - .asStringSet(List.of()) - ) - .withParkCost( - c - .of("carParkCost") - .since(V2_1) - .summary("Cost of parking a car.") - .asInt(VehicleParkingPreferences.DEFAULT.parkCost().toSeconds()) - ) - .withParkTime( - c - .of("carParkTime") - .since(V2_1) - .summary("Time to park a car") - .asDuration(VehicleParkingPreferences.DEFAULT.parkTime()) - ) - .withPreferredVehicleParkingTags( - c - .of("preferredVehicleParkingTags") - .since(V2_3) - .summary( - "Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised." - ) - .description( - """ - Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). - """ - ) - .asStringSet(List.of()) - ) - ) - .withRental(it -> setVehicleRental(c, it)); + .withParking(it -> mapParking(cc, it)) + .withRental(it -> mapRental(cc, it)); } private static void mapSystemPreferences(NodeAdapter c, SystemPreferences.Builder builder) { diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java new file mode 100644 index 00000000000..e4988b02767 --- /dev/null +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java @@ -0,0 +1,53 @@ +package org.opentripplanner.standalone.config.routerequest; + +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; + +import org.opentripplanner.routing.api.request.preference.TimeSlopeSafetyTriangle; +import org.opentripplanner.standalone.config.framework.json.NodeAdapter; + +public class TriangleOptimizationConfig { + + private static void mapTriangleParameters( + NodeAdapter c, + TimeSlopeSafetyTriangle.Builder builder + ) { + builder + .withTime( + c + .of("time") + .since(V2_0) + .summary("Relative importance of duration of travel (range 0-1).") + .asDouble(builder.time()) + ) + .withSlope( + c + .of("flatness") + .since(V2_0) + .summary("Relative importance of flat terrain (range 0-1).") + .asDouble(builder.slope()) + ) + .withSafety( + c + .of("safety") + .since(V2_0) + .summary("Relative importance of safety (range 0-1).") + .description( + """ + This factor can also include other concerns such as convenience and general cyclist + preferences by taking into account road surface etc. + """ + ) + .asDouble(builder.safety()) + ); + } + + static void mapOptimizationTriangle(NodeAdapter c, TimeSlopeSafetyTriangle.Builder preferences) { + var optimizationTriangle = c + .of("triangle") + .since(V2_5) + .summary("Triangle optimization criteria.") + .asObject(); + mapTriangleParameters(optimizationTriangle, preferences); + } +} diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java new file mode 100644 index 00000000000..951129bc7b7 --- /dev/null +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java @@ -0,0 +1,93 @@ +package org.opentripplanner.standalone.config.routerequest; + +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_1; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_3; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; + +import java.util.List; +import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; +import org.opentripplanner.standalone.config.framework.json.NodeAdapter; + +public class VehicleParkingConfig { + + private static void mapParkingPreferences( + NodeAdapter c, + VehicleParkingPreferences.Builder builder + ) { + builder + .withUnpreferredVehicleParkingTagCost( + c + .of("unpreferredVehicleParkingTagCost") + .since(V2_3) + .summary("What cost to add if a parking facility doesn't contain a preferred tag.") + .description("See `preferredVehicleParkingTags`.") + .asInt(VehicleParkingPreferences.DEFAULT.unpreferredVehicleParkingTagCost().toSeconds()) + ) + .withBannedVehicleParkingTags( + c + .of("bannedVehicleParkingTags") + .since(V2_1) + .summary( + "Tags with which a vehicle parking will not be used. If empty, no tags are banned." + ) + .description( + """ + Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + """ + ) + .asStringSet(List.of()) + ) + .withRequiredVehicleParkingTags( + c + .of("requiredVehicleParkingTags") + .since(V2_1) + .summary( + "Tags without which a vehicle parking will not be used. If empty, no tags are required." + ) + .description( + """ + Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + """ + ) + .asStringSet(List.of()) + ) + .withParkTime( + c + .of("parkTime") + .since(V2_0) + .summary("Time to park a vehicle.") + .asDuration(VehicleParkingPreferences.DEFAULT.parkTime()) + ) + .withParkCost( + c + .of("parkCost") + .since(V2_0) + .summary("Cost to park a vehicle.") + .asInt(VehicleParkingPreferences.DEFAULT.parkCost().toSeconds()) + ) + .withPreferredVehicleParkingTags( + c + .of("preferredVehicleParkingTags") + .since(V2_3) + .summary( + "Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised." + ) + .description( + """ + Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + """ + ) + .asStringSet(List.of()) + ); + } + + static void mapParking(NodeAdapter c, VehicleParkingPreferences.Builder preferences) { + var vehicleParking = c + .of("parking") + .since(V2_5) + .summary("Preferences for parking a vehicle.") + .asObject(); + mapParkingPreferences(vehicleParking, preferences); + } +} diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java index 057daa7001c..3d1534f5753 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java @@ -80,12 +80,8 @@ static void mapRentalPreferences(NodeAdapter c, VehicleRentalPreferences.Builder ); } - static void setVehicleRental(NodeAdapter c, VehicleRentalPreferences.Builder preferences) { - var vehicleRental = c - .of("vehicleRental") - .since(V2_3) - .summary("Vehicle rental options") - .asObject(); + static void mapRental(NodeAdapter c, VehicleRentalPreferences.Builder preferences) { + var vehicleRental = c.of("rental").since(V2_3).summary("Vehicle rental options").asObject(); mapRentalPreferences(vehicleRental, preferences); } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java new file mode 100644 index 00000000000..e8ccbffe4df --- /dev/null +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java @@ -0,0 +1,82 @@ +package org.opentripplanner.standalone.config.routerequest; + +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_1; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_3; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; + +import org.opentripplanner.routing.api.request.preference.VehicleWalkingPreferences; +import org.opentripplanner.standalone.config.framework.json.NodeAdapter; + +public class VehicleWalkingConfig { + + private static void mapVehicleWalkingPreferences( + NodeAdapter c, + VehicleWalkingPreferences.Builder builder + ) { + var dft = builder.original(); + builder + .withSpeed( + c + .of("speed") + .since(V2_1) + .summary( + "The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH." + ) + .asDouble(dft.speed()) + ) + .withReluctance( + c + .of("reluctance") + .since(V2_1) + .summary( + "A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time." + ) + .asDouble(dft.reluctance()) + ) + .withHopTime( + c + .of("hopTime") + .since(V2_0) + .summary("The time it takes the user to hop on or off a vehicle in seconds.") + .description( + """ + Time it takes to rent or park a vehicle have their own parameters and this is not meant + for controlling the duration of those events. + """ + ) + .asDuration(dft.hopTime()) + ) + .withHopCost( + c + .of("hopCost") + .since(V2_0) + .summary("The cost of hopping on or off a vehicle.") + .description( + """ + There are different parameters for the cost of renting or parking a vehicle and this is + not meant for controlling the cost of those events. + """ + ) + .asInt(dft.hopCost().toSeconds()) + ) + .withStairsReluctance( + c + .of("stairsReluctance") + .since(V2_3) + .summary( + "How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour." + ) + .asDouble(dft.stairsReluctance()) + ); + } + + static void mapVehicleWalking(NodeAdapter c, VehicleWalkingPreferences.Builder preferences) { + var vehicleWalking = c + .of("walking") + .since(V2_5) + .summary("Preferences for walking a vehicle.") + .asObject(); + mapVehicleWalkingPreferences(vehicleWalking, preferences); + } +} diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 69f859d784d..d9c1e8e8c19 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -13,15 +13,9 @@ }, "routingDefaults": { "walkSpeed": 1.3, - "bikeSpeed": 5, - "carSpeed": 40, "numItineraries": 12, "transferPenalty": 0, "walkReluctance": 4.0, - "bikeReluctance": 5.0, - "bikeWalkingReluctance": 10.0, - "bikeStairsReluctance": 150.0, - "carReluctance": 10.0, "stairsReluctance": 1.65, "turnReluctance": 1.0, "elevatorBoardTime": 90, @@ -29,17 +23,38 @@ "elevatorHopTime": 20, "elevatorHopCost": 20, "escalatorReluctance": 1.5, - "vehicleRental": { - "pickupCost": 120, - "dropOffTime": 30, - "dropOffCost": 30 + "bicycle": { + "speed": 5, + "reluctance": 5.0, + "boardCost": 600, + "walking": { + "reluctance": 10.0, + "stairsReluctance": 150.0 + }, + "rental": { + "pickupCost": 120, + "dropOffTime": 30, + "dropOffCost": 30 + }, + "parking": { + "parkTime": "1m", + "parkCost": 120 + } + }, + "car": { + "speed": 40, + "reluctance": 10, + "dropoffTime": 120, + "decelerationSpeed": 2.9, + "accelerationSpeed": 2.9, + "rental": { + "pickupCost": 120, + "dropOffTime": 30, + "dropOffCost": 30 + } }, - "bikeParkTime": "1m", - "bikeParkCost": 120, - "carDropoffTime": 120, "waitReluctance": 1.0, "walkBoardCost": 600, - "bikeBoardCost": 600, "otherThanPreferredRoutesPenalty": 300, "transferSlack": 120, // Default slack for any mode is 0 (zero) @@ -74,8 +89,6 @@ "minBikeParkingDistance": 300, "debug": "limit-to-search-window" }, - "carDecelerationSpeed": 2.9, - "carAccelerationSpeed": 2.9, "ignoreRealtimeUpdates": false, "geoidElevation": false, "maxJourneyDuration": "36h", diff --git a/test/performance/norway/speed-test-config.json b/test/performance/norway/speed-test-config.json index e673155eb4f..cef9b1ef061 100644 --- a/test/performance/norway/speed-test-config.json +++ b/test/performance/norway/speed-test-config.json @@ -41,8 +41,10 @@ "routingDefaults": { // Default is 1.4 m/s = ~ 5.0 km/t "walkSpeed": 1.4, - // Should not be used - a high cost indicate an error - "bikeBoardCost": 222000, + "bicycle": { + // Should not be used - a high cost indicate an error + "boardCost": 222000 + }, "walkBoardCost": 600, "transferPenalty": 0, "walkReluctance": 4.0, diff --git a/test/performance/switzerland/speed-test-config.json b/test/performance/switzerland/speed-test-config.json index f37c8497ffa..8b622825d09 100644 --- a/test/performance/switzerland/speed-test-config.json +++ b/test/performance/switzerland/speed-test-config.json @@ -41,8 +41,10 @@ "routingDefaults": { // Default is 1.4 m/s = ~ 5.0 km/t "walkSpeed": 1.4, - // Should not be used - a high cost indicate an error - "bikeBoardCost": 222000, + "bicycle": { + // Should not be used - a high cost indicate an error + "boardCost": 222000 + }, "walkBoardCost": 600, "transferPenalty": 0, "walkReluctance": 4.0, From d199e392e90062e810ea749312964eab21ab4851 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 18 Dec 2023 17:56:19 +0200 Subject: [PATCH 03/21] Make own wrapper for walk preferences in router-config --- docs/RouteRequest.md | 95 ++++++++++--------- docs/RouterConfiguration.md | 12 ++- docs/examples/entur/router-config.json | 10 +- docs/examples/ibi/portland/router-config.json | 6 +- .../examples/skanetrafiken/router-config.json | 4 +- .../routerequest/RouteRequestConfig.java | 23 ++--- .../standalone/config/router-config.json | 12 ++- .../performance/norway/speed-test-config.json | 10 +- .../skanetrafiken/speed-test-config.json | 6 +- .../switzerland/speed-test-config.json | 10 +- 10 files changed, 104 insertions(+), 84 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 755f5f73e28..f6b461c5212 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -23,7 +23,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | elevatorBoardTime | `integer` | How long does it take to get on an elevator, on average. | *Optional* | `90` | 2.0 | | elevatorHopCost | `integer` | What is the cost of travelling one floor on an elevator? | *Optional* | `20` | 2.0 | | elevatorHopTime | `integer` | How long does it take to advance one floor on an elevator? | *Optional* | `20` | 2.0 | -| escalatorReluctance | `double` | A multiplier for how bad being in an escalator is compared to being in transit for equal lengths of time | *Optional* | `1.5` | 2.4 | | geoidElevation | `boolean` | If true, the Graph's ellipsoidToGeoidDifference is applied to all elevations returned by this query. | *Optional* | `false` | 2.0 | | ignoreRealtimeUpdates | `boolean` | When true, real-time updates are ignored during this search. | *Optional* | `false` | 2.0 | | [intersectionTraversalModel](#rd_intersectionTraversalModel) | `enum` | The model that computes the costs of turns. | *Optional* | `"simple"` | 2.2 | @@ -37,18 +36,12 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | [relaxTransitPriorityGroup](#rd_relaxTransitPriorityGroup) | `string` | The relax function for transit-priority-groups | *Optional* | `"0s + 1.00 t"` | 2.5 | | [relaxTransitSearchGeneralizedCostAtDestination](#rd_relaxTransitSearchGeneralizedCostAtDestination) | `double` | Whether non-optimal transit paths at the destination should be returned | *Optional* | | 2.3 | | [searchWindow](#rd_searchWindow) | `duration` | The duration of the search-window. | *Optional* | | 2.0 | -| stairsReluctance | `double` | Used instead of walkReluctance for stairs. | *Optional* | `2.0` | 2.0 | -| [stairsTimeFactor](#rd_stairsTimeFactor) | `double` | How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length. | *Optional* | `3.0` | 2.1 | | [streetRoutingTimeout](#rd_streetRoutingTimeout) | `duration` | The maximum time a street routing request is allowed to take before returning the results. | *Optional* | `"PT5S"` | 2.2 | | [transferPenalty](#rd_transferPenalty) | `integer` | An additional penalty added to boardings after the first. | *Optional* | `0` | 2.0 | | [transferSlack](#rd_transferSlack) | `integer` | The extra time needed to make a safe transfer in seconds. | *Optional* | `120` | 2.0 | | turnReluctance | `double` | Multiplicative factor on expected turning time. | *Optional* | `1.0` | 2.0 | | [unpreferredCost](#rd_unpreferredCost) | `cost-linear-function` | A cost function used to calculate penalty for an unpreferred route. | *Optional* | `"0s + 1.00 t"` | 2.2 | | waitReluctance | `double` | How much worse is waiting for a transit vehicle than being on a transit vehicle, as a multiplier. | *Optional* | `1.0` | 2.0 | -| walkBoardCost | `integer` | Prevents unnecessary transfers by adding a cost for boarding a vehicle. This is the cost that is used when boarding while walking. | *Optional* | `600` | 2.0 | -| [walkReluctance](#rd_walkReluctance) | `double` | A multiplier for how bad walking is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | -| [walkSafetyFactor](#rd_walkSafetyFactor) | `double` | Factor for how much the walk safety is considered in routing. | *Optional* | `1.0` | 2.2 | -| walkSpeed | `double` | The user's walking speed in meters/second. | *Optional* | `1.33` | 2.0 | | accessEgress | `object` | Parameters for access and egress routing. | *Optional* | | 2.4 | |    [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 | @@ -134,6 +127,14 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | [unpreferred](#rd_unpreferred) | `object` | Parameters listing authorities or lines that preferably should not be used in trip patters. | *Optional* | | 2.2 | |    [agencies](#rd_unpreferred_agencies) | `feed-scoped-id[]` | The ids of the agencies that incur an extra cost when being used. Format: `FeedId:AgencyId` | *Optional* | | 2.2 | |    [routes](#rd_unpreferred_routes) | `feed-scoped-id[]` | The ids of the routes that incur an extra cost when being used. Format: `FeedId:RouteId` | *Optional* | | 2.2 | +| walk | `object` | Walking preferences. | *Optional* | | 2.5 | +|    boardCost | `integer` | Prevents unnecessary transfers by adding a cost for boarding a vehicle. This is the cost that is used when boarding while walking. | *Optional* | `600` | 2.0 | +|    escalatorReluctance | `double` | A multiplier for how bad being in an escalator is compared to being in transit for equal lengths of time | *Optional* | `1.5` | 2.4 | +|    [reluctance](#rd_walk_reluctance) | `double` | A multiplier for how bad walking is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | +|    [safetyFactor](#rd_walk_safetyFactor) | `double` | Factor for how much the walk safety is considered in routing. | *Optional* | `1.0` | 2.2 | +|    speed | `double` | The user's walking speed in meters/second. | *Optional* | `1.33` | 2.0 | +|    stairsReluctance | `double` | Used instead of walkReluctance for stairs. | *Optional* | `2.0` | 2.0 | +|    [stairsTimeFactor](#rd_walk_stairsTimeFactor) | `double` | How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length. | *Optional* | `3.0` | 2.1 | | wheelchairAccessibility | `object` | See [Wheelchair Accessibility](Accessibility.md) | *Optional* | | 2.2 | |    enabled | `boolean` | Enable wheelchair accessibility. | *Optional* | `false` | 2.0 | |    inaccessibleStreetReluctance | `double` | The factor to multiply the cost of traversing a street edge that is not wheelchair-accessible. | *Optional* | `25.0` | 2.2 | @@ -297,17 +298,6 @@ There is no need to set this when going to the next/previous page. The OTP Serve increase/decrease the search-window when paging to match the requested number of itineraries. -

stairsTimeFactor

- -**Since version:** `2.1` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `3.0` -**Path:** /routingDefaults - -How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length. - -Default value is based on: Fujiyama, T., & Tyler, N. (2010). Predicting the walking -speed of pedestrians on stairs. Transportation Planning and Technology, 33(2), 177–202. - -

streetRoutingTimeout

**Since version:** `2.2` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT5S"` @@ -358,29 +348,6 @@ Function should return number of seconds that we are willing to wait for preferr or for an unpreferred agency's departure. For example: `5m + 2.0 t` -

walkReluctance

- -**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `2.0` -**Path:** /routingDefaults - -A multiplier for how bad walking is, compared to being in transit for equal lengths of time. - -Empirically, values between 2 and 4 seem to correspond well to the concept of not wanting to walk -too much without asking for totally ridiculous itineraries, but this observation should in no way -be taken as scientific or definitive. Your mileage may vary. -See https://github.com/opentripplanner/OpenTripPlanner/issues/4090 for impact on performance with -high values. - - -

walkSafetyFactor

- -**Since version:** `2.2` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `1.0` -**Path:** /routingDefaults - -Factor for how much the walk safety is considered in routing. - -Value should be between 0 and 1. If the value is set to be 0, safety is ignored. -

maxDuration

**Since version:** `2.1` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT45M"` @@ -934,6 +901,40 @@ The ids of the routes that incur an extra cost when being used. Format: `FeedId: How much cost is added is configured in `unpreferredCost`. +

reluctance

+ +**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `2.0` +**Path:** /routingDefaults/walk + +A multiplier for how bad walking is, compared to being in transit for equal lengths of time. + +Empirically, values between 2 and 4 seem to correspond well to the concept of not wanting to walk +too much without asking for totally ridiculous itineraries, but this observation should in no way +be taken as scientific or definitive. Your mileage may vary. +See https://github.com/opentripplanner/OpenTripPlanner/issues/4090 for impact on performance with +high values. + + +

safetyFactor

+ +**Since version:** `2.2` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `1.0` +**Path:** /routingDefaults/walk + +Factor for how much the walk safety is considered in routing. + +Value should be between 0 and 1. If the value is set to be 0, safety is ignored. + +

stairsTimeFactor

+ +**Since version:** `2.1` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `3.0` +**Path:** /routingDefaults/walk + +How much more time does it take to walk a flight of stairs compared to walking a similar horizontal length. + +Default value is based on: Fujiyama, T., & Tyler, N. (2010). Predicting the walking +speed of pedestrians on stairs. Transportation Planning and Technology, 33(2), 177–202. + +

maxSlope

**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.083` @@ -980,17 +981,13 @@ include stairs as a last result. // router-config.json { "routingDefaults" : { - "walkSpeed" : 1.3, "numItineraries" : 12, "transferPenalty" : 0, - "walkReluctance" : 4.0, - "stairsReluctance" : 1.65, "turnReluctance" : 1.0, "elevatorBoardTime" : 90, "elevatorBoardCost" : 90, "elevatorHopTime" : 20, "elevatorHopCost" : 20, - "escalatorReluctance" : 1.5, "bicycle" : { "speed" : 5, "reluctance" : 5.0, @@ -1021,8 +1018,14 @@ include stairs as a last result. "dropOffCost" : 30 } }, + "walk" : { + "speed" : 1.3, + "reluctance" : 4.0, + "stairsReluctance" : 1.65, + "boardCost" : 600, + "escalatorReluctance" : 1.5 + }, "waitReluctance" : 1.0, - "walkBoardCost" : 600, "otherThanPreferredRoutesPenalty" : 300, "transferSlack" : 120, "boardSlackForMode" : { diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 37a673ea7a2..35020637894 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -451,17 +451,13 @@ Used to group requests when monitoring OTP. ] }, "routingDefaults" : { - "walkSpeed" : 1.3, "numItineraries" : 12, "transferPenalty" : 0, - "walkReluctance" : 4.0, - "stairsReluctance" : 1.65, "turnReluctance" : 1.0, "elevatorBoardTime" : 90, "elevatorBoardCost" : 90, "elevatorHopTime" : 20, "elevatorHopCost" : 20, - "escalatorReluctance" : 1.5, "bicycle" : { "speed" : 5, "reluctance" : 5.0, @@ -492,8 +488,14 @@ Used to group requests when monitoring OTP. "dropOffCost" : 30 } }, + "walk" : { + "speed" : 1.3, + "reluctance" : 4.0, + "stairsReluctance" : 1.65, + "boardCost" : 600, + "escalatorReluctance" : 1.5 + }, "waitReluctance" : 1.0, - "walkBoardCost" : 600, "otherThanPreferredRoutesPenalty" : 300, "transferSlack" : 120, "boardSlackForMode" : { diff --git a/docs/examples/entur/router-config.json b/docs/examples/entur/router-config.json index 2d217cb2402..cd4736263ce 100644 --- a/docs/examples/entur/router-config.json +++ b/docs/examples/entur/router-config.json @@ -1,11 +1,8 @@ { "configVersion" : "{{ Entur CI config build number inserted here }}", "routingDefaults": { - "walkSpeed": 1.3, "numItineraries": 12, "transferPenalty": 0, - "walkReluctance": 4.0, - "stairsReluctance": 1.65, "turnReluctance": 1.0, "elevatorBoardTime": 90, "elevatorBoardCost": 90, @@ -40,8 +37,13 @@ "dropOffCost": 30 } }, + "walk": { + "speed": 1.3, + "reluctance": 4.0, + "stairsReluctance": 1.65, + "boardCost": 600 + }, "waitReluctance": 1.0, - "walkBoardCost": 600, "otherThanPreferredRoutesPenalty": 300, "transferSlack": 120, // Default slack for any mode is 0 (zero) diff --git a/docs/examples/ibi/portland/router-config.json b/docs/examples/ibi/portland/router-config.json index 55a487fcfdc..445738762a1 100644 --- a/docs/examples/ibi/portland/router-config.json +++ b/docs/examples/ibi/portland/router-config.json @@ -5,8 +5,10 @@ "alightSlack": "0s", "transferSlack": 180, "waitReluctance": 0.9, - "walkReluctance": 1.75, - "stairsReluctance": 1.65, + "walk": { + "reluctance": 1.75, + "stairsReluctance": 1.65 + }, "numItineraries": 3, "geoidElevation": true, "streetRoutingTimeout": "7s" diff --git a/docs/examples/skanetrafiken/router-config.json b/docs/examples/skanetrafiken/router-config.json index ddec543e516..d65604aaa00 100644 --- a/docs/examples/skanetrafiken/router-config.json +++ b/docs/examples/skanetrafiken/router-config.json @@ -5,7 +5,9 @@ }, "transferSlack": 180, "waitReluctance": 0.175, - "walkReluctance": 5, + "walk": { + "reluctance": 5 + }, "maxDirectStreetDuration": "3700s" }, "transit": { diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 0ff1c48cf2b..f15f6acdfe1 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -677,17 +677,18 @@ private static void mapSystemPreferences(NodeAdapter c, SystemPreferences.Builde private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder walk) { var dft = walk.original(); + NodeAdapter cw = c.of("walk").since(V2_5).summary("Walking preferences.").asObject(); walk .withSpeed( - c - .of("walkSpeed") + cw + .of("speed") .since(V2_0) .summary("The user's walking speed in meters/second.") .asDouble(dft.speed()) ) .withReluctance( - c - .of("walkReluctance") + cw + .of("reluctance") .since(V2_0) .summary( "A multiplier for how bad walking is, compared to being in transit for equal lengths of time." @@ -704,8 +705,8 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asDouble(dft.reluctance()) ) .withBoardCost( - c - .of("walkBoardCost") + cw + .of("boardCost") .since(V2_0) .summary( """ @@ -716,14 +717,14 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asInt(dft.boardCost()) ) .withStairsReluctance( - c + cw .of("stairsReluctance") .since(V2_0) .summary("Used instead of walkReluctance for stairs.") .asDouble(dft.stairsReluctance()) ) .withStairsTimeFactor( - c + cw .of("stairsTimeFactor") .since(V2_1) .summary( @@ -738,8 +739,8 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asDouble(dft.stairsTimeFactor()) ) .withSafetyFactor( - c - .of("walkSafetyFactor") + cw + .of("safetyFactor") .since(V2_2) .summary("Factor for how much the walk safety is considered in routing.") .description( @@ -748,7 +749,7 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asDouble(dft.safetyFactor()) ) .withEscalatorReluctance( - c + cw .of("escalatorReluctance") .since(V2_4) .summary( diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index d9c1e8e8c19..1d023c25688 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -12,17 +12,13 @@ ] }, "routingDefaults": { - "walkSpeed": 1.3, "numItineraries": 12, "transferPenalty": 0, - "walkReluctance": 4.0, - "stairsReluctance": 1.65, "turnReluctance": 1.0, "elevatorBoardTime": 90, "elevatorBoardCost": 90, "elevatorHopTime": 20, "elevatorHopCost": 20, - "escalatorReluctance": 1.5, "bicycle": { "speed": 5, "reluctance": 5.0, @@ -53,8 +49,14 @@ "dropOffCost": 30 } }, + "walk": { + "speed": 1.3, + "reluctance": 4.0, + "stairsReluctance": 1.65, + "boardCost": 600, + "escalatorReluctance": 1.5 + }, "waitReluctance": 1.0, - "walkBoardCost": 600, "otherThanPreferredRoutesPenalty": 300, "transferSlack": 120, // Default slack for any mode is 0 (zero) diff --git a/test/performance/norway/speed-test-config.json b/test/performance/norway/speed-test-config.json index cef9b1ef061..e4ca99d7fe5 100644 --- a/test/performance/norway/speed-test-config.json +++ b/test/performance/norway/speed-test-config.json @@ -39,15 +39,17 @@ } }, "routingDefaults": { - // Default is 1.4 m/s = ~ 5.0 km/t - "walkSpeed": 1.4, "bicycle": { // Should not be used - a high cost indicate an error "boardCost": 222000 }, - "walkBoardCost": 600, + "walk": { + // Default is 1.4 m/s = ~ 5.0 km/t + "speed": 1.4, + "boardCost": 600, + "reluctance": 4.0 + }, "transferPenalty": 0, - "walkReluctance": 4.0, "waitReluctance": 1.0, "boardSlack": "30s", "alightSlack": "15s", diff --git a/test/performance/skanetrafiken/speed-test-config.json b/test/performance/skanetrafiken/speed-test-config.json index a43cc97095d..66184ab124f 100644 --- a/test/performance/skanetrafiken/speed-test-config.json +++ b/test/performance/skanetrafiken/speed-test-config.json @@ -15,10 +15,12 @@ } }, "routingDefaults": { - "walkSpeed": 1.38, + "walk": { + "speed": 1.38, + "reluctance": 5 + }, "transferSlack": 180, "waitReluctance": 0.175, - "walkReluctance": 5, "maxDirectStreetDuration": "1h1m", "boardSlackForMode": { "RAIL": "12m" diff --git a/test/performance/switzerland/speed-test-config.json b/test/performance/switzerland/speed-test-config.json index 8b622825d09..19ac7a1358a 100644 --- a/test/performance/switzerland/speed-test-config.json +++ b/test/performance/switzerland/speed-test-config.json @@ -39,15 +39,17 @@ } }, "routingDefaults": { - // Default is 1.4 m/s = ~ 5.0 km/t - "walkSpeed": 1.4, "bicycle": { // Should not be used - a high cost indicate an error "boardCost": 222000 }, - "walkBoardCost": 600, + "walk": { + // Default is 1.4 m/s = ~ 5.0 km/t + "speed": 1.4, + "boardCost": 600, + "reluctance": 4.0 + }, "transferPenalty": 0, - "walkReluctance": 4.0, "waitReluctance": 1.0, "boardSlack": "30s", "alightSlack": "15s", From 845532a26090ad1954f9595b81bed3ba0b756de7 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Mon, 18 Dec 2023 18:12:08 +0200 Subject: [PATCH 04/21] Rename walking -> walk --- docs/RouteRequest.md | 16 ++++++++-------- docs/RouterConfiguration.md | 2 +- docs/examples/entur/router-config.json | 2 +- .../routerequest/VehicleWalkingConfig.java | 2 +- .../standalone/config/router-config.json | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index f6b461c5212..6577789f361 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -74,9 +74,9 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       [allowedNetworks](#rd_bicycle_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | |       [bannedNetworks](#rd_bicycle_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | |    triangle | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | -|    walking | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | -|       [hopCost](#rd_bicycle_walking_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | -|       [hopTime](#rd_bicycle_walking_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle in seconds. | *Optional* | `"PT0S"` | 2.0 | +|    walk | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | +|       [hopCost](#rd_bicycle_walk_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | +|       [hopTime](#rd_bicycle_walk_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle in seconds. | *Optional* | `"PT0S"` | 2.0 | |       reluctance | `double` | A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | |       speed | `double` | The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | |       stairsReluctance | `double` | How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | @@ -495,10 +495,10 @@ The vehicle rental networks which may be used. If empty all networks may be used The vehicle rental networks which may not be used. If empty, no networks are banned. -

hopCost

+

hopCost

**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0` -**Path:** /routingDefaults/bicycle/walking +**Path:** /routingDefaults/bicycle/walk The cost of hopping on or off a vehicle. @@ -506,10 +506,10 @@ There are different parameters for the cost of renting or parking a vehicle and not meant for controlling the cost of those events. -

hopTime

+

hopTime

**Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` -**Path:** /routingDefaults/bicycle/walking +**Path:** /routingDefaults/bicycle/walk The time it takes the user to hop on or off a vehicle in seconds. @@ -992,7 +992,7 @@ include stairs as a last result. "speed" : 5, "reluctance" : 5.0, "boardCost" : 600, - "walking" : { + "walk" : { "reluctance" : 10.0, "stairsReluctance" : 150.0 }, diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 35020637894..a1541288c75 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -462,7 +462,7 @@ Used to group requests when monitoring OTP. "speed" : 5, "reluctance" : 5.0, "boardCost" : 600, - "walking" : { + "walk" : { "reluctance" : 10.0, "stairsReluctance" : 150.0 }, diff --git a/docs/examples/entur/router-config.json b/docs/examples/entur/router-config.json index cd4736263ce..06ee5590eed 100644 --- a/docs/examples/entur/router-config.json +++ b/docs/examples/entur/router-config.json @@ -12,7 +12,7 @@ "speed": 5, "reluctance": 5.0, "boardCost": 600, - "walking": { + "walk": { "reluctance": 10.0 }, "rental": { diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java index e8ccbffe4df..ac6ac7d92f4 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java @@ -73,7 +73,7 @@ private static void mapVehicleWalkingPreferences( static void mapVehicleWalking(NodeAdapter c, VehicleWalkingPreferences.Builder preferences) { var vehicleWalking = c - .of("walking") + .of("walk") .since(V2_5) .summary("Preferences for walking a vehicle.") .asObject(); diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 1d023c25688..996505b5296 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -23,7 +23,7 @@ "speed": 5, "reluctance": 5.0, "boardCost": 600, - "walking": { + "walk": { "reluctance": 10.0, "stairsReluctance": 150.0 }, From ee99250f7184e790e145e711e0a7ed15f73cb806 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Fri, 29 Dec 2023 18:30:29 +0200 Subject: [PATCH 05/21] Rename/type rental preferences and remove unused carDropoffTime --- docs/RouteRequest.md | 18 ++-- docs/RouterConfiguration.md | 5 +- docs/examples/entur/router-config.json | 5 +- docs/examples/ibi/atlanta/router-config.json | 4 +- .../common/RequestToPreferencesMapper.java | 2 +- .../model/DefaultRouteRequestType.java | 10 +- .../request/preference/CarPreferences.java | 21 ---- .../preference/VehicleRentalPreferences.java | 100 ++++++++++-------- .../street/VehicleRentalEdge.java | 10 +- .../routerequest/RouteRequestConfig.java | 9 -- .../routerequest/VehicleRentalConfig.java | 22 ++-- .../model/edge/StreetTransitEntityLink.java | 2 +- .../street/model/edge/TemporaryFreeEdge.java | 2 +- .../preference/BikePreferencesTest.java | 4 - .../preference/CarPreferencesTest.java | 8 -- .../VehicleRentalPreferencesTest.java | 25 +++-- .../street/integration/BikeRentalTest.java | 2 +- .../standalone/config/router-config.json | 5 +- 18 files changed, 118 insertions(+), 136 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 6577789f361..aff3f3e5758 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -66,10 +66,10 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | |       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | |       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|       dropOffTime | `integer` | Time to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|       keepingAtDestinationCost | `double` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0.0` | 2.2 | +|       dropOffTime | `duration` | Time to drop-off a rented vehicle. | *Optional* | `"PT30S"` | 2.0 | +|       keepingAtDestinationCost | `integer` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0` | 2.2 | |       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | -|       pickupTime | `integer` | Time to rent a vehicle. | *Optional* | `60` | 2.0 | +|       pickupTime | `duration` | Time to rent a vehicle. | *Optional* | `"PT1M"` | 2.0 | |       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | |       [allowedNetworks](#rd_bicycle_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | |       [bannedNetworks](#rd_bicycle_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | @@ -84,7 +84,6 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | car | `object` | Car preferences. | *Optional* | | 2.5 | |    accelerationSpeed | `double` | The acceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | |    decelerationSpeed | `double` | The deceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | -|    dropoffTime | `integer` | Time to park a car in a park and ride, w/o taking into account driving and walking cost. | *Optional* | `120` | 2.0 | |    pickupCost | `integer` | Add a cost for car pickup changes when a pickup or drop off takes place | *Optional* | `120` | 2.1 | |    pickupTime | `integer` | Add a time for car pickup changes when a pickup or drop off takes place | *Optional* | `60` | 2.1 | |    reluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | @@ -93,10 +92,10 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | |       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | |       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|       dropOffTime | `integer` | Time to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | -|       keepingAtDestinationCost | `double` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0.0` | 2.2 | +|       dropOffTime | `duration` | Time to drop-off a rented vehicle. | *Optional* | `"PT30S"` | 2.0 | +|       keepingAtDestinationCost | `integer` | The cost of arriving at the destination with the rented vehicle, to discourage doing so. | *Optional* | `0` | 2.2 | |       pickupCost | `integer` | Cost to rent a vehicle. | *Optional* | `120` | 2.0 | -|       pickupTime | `integer` | Time to rent a vehicle. | *Optional* | `60` | 2.0 | +|       pickupTime | `duration` | Time to rent a vehicle. | *Optional* | `"PT1M"` | 2.0 | |       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | |       [allowedNetworks](#rd_car_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | |       [bannedNetworks](#rd_car_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | @@ -998,7 +997,7 @@ include stairs as a last result. }, "rental" : { "pickupCost" : 120, - "dropOffTime" : 30, + "dropOffTime" : "30s", "dropOffCost" : 30 }, "parking" : { @@ -1009,12 +1008,11 @@ include stairs as a last result. "car" : { "speed" : 40, "reluctance" : 10, - "dropoffTime" : 120, "decelerationSpeed" : 2.9, "accelerationSpeed" : 2.9, "rental" : { "pickupCost" : 120, - "dropOffTime" : 30, + "dropOffTime" : "30s", "dropOffCost" : 30 } }, diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index a1541288c75..af2c0a9630a 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -468,7 +468,7 @@ Used to group requests when monitoring OTP. }, "rental" : { "pickupCost" : 120, - "dropOffTime" : 30, + "dropOffTime" : "30s", "dropOffCost" : 30 }, "parking" : { @@ -479,12 +479,11 @@ Used to group requests when monitoring OTP. "car" : { "speed" : 40, "reluctance" : 10, - "dropoffTime" : 120, "decelerationSpeed" : 2.9, "accelerationSpeed" : 2.9, "rental" : { "pickupCost" : 120, - "dropOffTime" : 30, + "dropOffTime" : "30s", "dropOffCost" : 30 } }, diff --git a/docs/examples/entur/router-config.json b/docs/examples/entur/router-config.json index 06ee5590eed..cd8a393a3c3 100644 --- a/docs/examples/entur/router-config.json +++ b/docs/examples/entur/router-config.json @@ -17,7 +17,7 @@ }, "rental": { "pickupCost": 120, - "dropOffTime": 30, + "dropOffTime": "30s", "dropOffCost": 30 }, "parking": { @@ -28,12 +28,11 @@ "car": { "speed": 40, "reluctance": 4.0, - "dropoffTime": 120, "decelerationSpeed": 2.9, "accelerationSpeed": 2.9, "rental": { "pickupCost": 120, - "dropOffTime": 30, + "dropOffTime": "30s", "dropOffCost": 30 } }, diff --git a/docs/examples/ibi/atlanta/router-config.json b/docs/examples/ibi/atlanta/router-config.json index 2aeb3e6434e..909c164ec43 100644 --- a/docs/examples/ibi/atlanta/router-config.json +++ b/docs/examples/ibi/atlanta/router-config.json @@ -7,13 +7,13 @@ "safety": 0.4 }, "rental": { - "pickupTime": 180, + "pickupTime": "3m", "pickupCost": 850 } }, "car": { "rental": { - "pickupTime": 180, + "pickupTime": "3m", "pickupCost": 850 } }, diff --git a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java index 68e61d6fe4e..5da43e9a179 100644 --- a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java @@ -147,7 +147,7 @@ private void mapRental(VehicleRentalPreferences.Builder rental) { setIfNotNull( req.keepingRentedBicycleAtDestinationCost, - rental::withArrivingInRentalVehicleAtDestinationCost + cost -> rental.withArrivingInRentalVehicleAtDestinationCost((int) Math.round(cost)) ); rental.withUseAvailabilityInformation(isPlannedForNow); } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java index 5e4dca2bfc2..aadd73dcddb 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java @@ -184,7 +184,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeRentalPickupTime") .description("Time to rent a bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.bike().rental().pickupTime()) + .dataFetcher(env -> (int) preferences.bike().rental().pickupTime().toSeconds()) .build() ) .field( @@ -193,7 +193,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeRentalPickupCost") .description("Cost to rent a bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.bike().rental().pickupCost()) + .dataFetcher(env -> preferences.bike().rental().pickupCost().toSeconds()) .build() ) .field( @@ -202,7 +202,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeRentalDropOffTime") .description("Time to drop-off a rented bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.bike().rental().dropoffTime()) + .dataFetcher(env -> (int) preferences.bike().rental().dropOffTime().toSeconds()) .build() ) .field( @@ -211,7 +211,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeRentalDropOffCost") .description("Cost to drop-off a rented bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.bike().rental().dropoffCost()) + .dataFetcher(env -> preferences.bike().rental().dropOffCost().toSeconds()) .build() ) .field( @@ -240,7 +240,7 @@ private GraphQLObjectType createGraphQLType() { "Time to park a car in a park and ride, w/o taking into account driving and walking cost." ) .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.car().dropoffTime()) + .dataFetcher(env -> 0) .build() ) .field( diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java index 6b103e8f3b7..9615a586335 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java @@ -27,7 +27,6 @@ public final class CarPreferences implements Serializable { private final VehicleRentalPreferences rental; private final int pickupTime; private final Cost pickupCost; - private final int dropoffTime; private final double accelerationSpeed; private final double decelerationSpeed; @@ -39,7 +38,6 @@ private CarPreferences() { this.rental = VehicleRentalPreferences.DEFAULT; this.pickupTime = 60; this.pickupCost = Cost.costOfMinutes(2); - this.dropoffTime = 120; this.accelerationSpeed = 2.9; this.decelerationSpeed = 2.9; } @@ -51,7 +49,6 @@ private CarPreferences(Builder builder) { this.rental = builder.rental; this.pickupTime = Units.duration(builder.pickupTime); this.pickupCost = builder.pickupCost; - this.dropoffTime = Units.duration(builder.dropoffTime); this.accelerationSpeed = Units.acceleration(builder.accelerationSpeed); this.decelerationSpeed = Units.acceleration(builder.decelerationSpeed); } @@ -97,14 +94,6 @@ public int pickupCost() { return pickupCost.toSeconds(); } - /** - * Time to park a car in a park and ride, w/o taking into account driving and walking cost (time - * to park, switch off, pick your stuff, lock the car, etc...) - */ - public int dropoffTime() { - return dropoffTime; - } - /** * The acceleration speed of an automobile, in meters per second per second. * Default is 2.9 m/s^2 (0 mph to 65 mph in 10 seconds) @@ -133,7 +122,6 @@ public boolean equals(Object o) { rental.equals(that.rental) && pickupTime == that.pickupTime && pickupCost.equals(that.pickupCost) && - dropoffTime == that.dropoffTime && DoubleUtils.doubleEquals(that.accelerationSpeed, accelerationSpeed) && DoubleUtils.doubleEquals(that.decelerationSpeed, decelerationSpeed) ); @@ -148,7 +136,6 @@ public int hashCode() { rental, pickupTime, pickupCost, - dropoffTime, accelerationSpeed, decelerationSpeed ); @@ -164,7 +151,6 @@ public String toString() { .addObj("rental", rental, DEFAULT.rental) .addNum("pickupTime", pickupTime, DEFAULT.pickupTime) .addObj("pickupCost", pickupCost, DEFAULT.pickupCost) - .addNum("dropoffTime", dropoffTime, DEFAULT.dropoffTime) .addNum("accelerationSpeed", accelerationSpeed, DEFAULT.accelerationSpeed) .addNum("decelerationSpeed", decelerationSpeed, DEFAULT.decelerationSpeed) .toString(); @@ -180,7 +166,6 @@ public static class Builder { private VehicleRentalPreferences rental; private int pickupTime; private Cost pickupCost; - private int dropoffTime; private double accelerationSpeed; private double decelerationSpeed; @@ -192,7 +177,6 @@ public Builder(CarPreferences original) { this.rental = original.rental; this.pickupTime = original.pickupTime; this.pickupCost = original.pickupCost; - this.dropoffTime = original.dropoffTime; this.accelerationSpeed = original.accelerationSpeed; this.decelerationSpeed = original.decelerationSpeed; } @@ -231,11 +215,6 @@ public Builder withPickupCost(int pickupCost) { return this; } - public Builder withDropoffTime(int dropoffTime) { - this.dropoffTime = dropoffTime; - return this; - } - public Builder withAccelerationSpeed(double accelerationSpeed) { this.accelerationSpeed = accelerationSpeed; return this; diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java index 8e18d2a81d5..6c9bbfea875 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferences.java @@ -1,10 +1,10 @@ package org.opentripplanner.routing.api.request.preference; import java.io.Serializable; +import java.time.Duration; import java.util.Objects; import java.util.Set; import java.util.function.Consumer; -import org.opentripplanner.framework.lang.DoubleUtils; import org.opentripplanner.framework.model.Cost; import org.opentripplanner.framework.model.Units; import org.opentripplanner.framework.tostring.ToStringBuilder; @@ -17,38 +17,38 @@ public final class VehicleRentalPreferences implements Serializable { public static final VehicleRentalPreferences DEFAULT = new VehicleRentalPreferences(); - private final int pickupTime; + private final Duration pickupTime; private final Cost pickupCost; - private final int dropoffTime; - private final Cost dropoffCost; + private final Duration dropOffTime; + private final Cost dropOffCost; private final boolean useAvailabilityInformation; - private final double arrivingInRentalVehicleAtDestinationCost; + private final Cost arrivingInRentalVehicleAtDestinationCost; private final boolean allowArrivingInRentedVehicleAtDestination; private final Set allowedNetworks; private final Set bannedNetworks; private VehicleRentalPreferences() { - this.pickupTime = 60; + this.pickupTime = Duration.ofMinutes(1); this.pickupCost = Cost.costOfMinutes(2); - this.dropoffTime = 30; - this.dropoffCost = Cost.costOfSeconds(30); + this.dropOffTime = Duration.ofSeconds(30); + this.dropOffCost = Cost.costOfSeconds(30); this.useAvailabilityInformation = false; - this.arrivingInRentalVehicleAtDestinationCost = 0; + this.arrivingInRentalVehicleAtDestinationCost = Cost.costOfSeconds(0); this.allowArrivingInRentedVehicleAtDestination = false; this.allowedNetworks = Set.of(); this.bannedNetworks = Set.of(); } private VehicleRentalPreferences(Builder builder) { - this.pickupTime = builder.pickupTime; + this.pickupTime = Duration.ofSeconds(Units.duration(builder.pickupTime)); this.pickupCost = builder.pickupCost; - this.dropoffTime = builder.dropoffTime; - this.dropoffCost = builder.dropoffCost; + this.dropOffTime = Duration.ofSeconds(Units.duration(builder.dropOffTime)); + this.dropOffCost = builder.dropOffCost; this.useAvailabilityInformation = builder.useAvailabilityInformation; this.arrivingInRentalVehicleAtDestinationCost = - DoubleUtils.roundTo1Decimal(builder.arrivingInRentalVehicleAtDestinationCost); + builder.arrivingInRentalVehicleAtDestinationCost; this.allowArrivingInRentedVehicleAtDestination = builder.allowArrivingInRentedVehicleAtDestination; this.allowedNetworks = builder.allowedNetworks; @@ -64,7 +64,7 @@ public Builder copyOf() { } /** Time to rent a vehicle */ - public int pickupTime() { + public Duration pickupTime() { return pickupTime; } @@ -72,18 +72,18 @@ public int pickupTime() { * Cost of renting a vehicle. The cost is a bit more than actual time to model the associated cost * and trouble. */ - public int pickupCost() { - return pickupCost.toSeconds(); + public Cost pickupCost() { + return pickupCost; } /** Time to drop-off a rented vehicle */ - public int dropoffTime() { - return dropoffTime; + public Duration dropOffTime() { + return dropOffTime; } /** Cost of dropping-off a rented vehicle */ - public int dropoffCost() { - return dropoffCost.toSeconds(); + public Cost dropOffCost() { + return dropOffCost; } /** @@ -97,7 +97,7 @@ public boolean useAvailabilityInformation() { /** * The cost of arriving at the destination with the rented vehicle, to discourage doing so. */ - public double arrivingInRentalVehicleAtDestinationCost() { + public Cost arrivingInRentalVehicleAtDestinationCost() { return arrivingInRentalVehicleAtDestinationCost; } @@ -127,16 +127,15 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; VehicleRentalPreferences that = (VehicleRentalPreferences) o; return ( - pickupTime == that.pickupTime && + Objects.equals(pickupTime, that.pickupTime) && Objects.equals(pickupCost, that.pickupCost) && - dropoffTime == that.dropoffTime && - Objects.equals(dropoffCost, that.dropoffCost) && + Objects.equals(dropOffTime, that.dropOffTime) && + Objects.equals(dropOffCost, that.dropOffCost) && useAvailabilityInformation == that.useAvailabilityInformation && - Double.compare( + Objects.equals( that.arrivingInRentalVehicleAtDestinationCost, arrivingInRentalVehicleAtDestinationCost - ) == - 0 && + ) && allowArrivingInRentedVehicleAtDestination == that.allowArrivingInRentedVehicleAtDestination && allowedNetworks.equals(that.allowedNetworks) && bannedNetworks.equals(that.bannedNetworks) @@ -148,8 +147,8 @@ public int hashCode() { return Objects.hash( pickupTime, pickupCost, - dropoffTime, - dropoffCost, + dropOffTime, + dropOffCost, useAvailabilityInformation, arrivingInRentalVehicleAtDestinationCost, allowArrivingInRentedVehicleAtDestination, @@ -162,12 +161,12 @@ public int hashCode() { public String toString() { return ToStringBuilder .of(VehicleRentalPreferences.class) - .addDurationSec("pickupTime", pickupTime, DEFAULT.pickupTime) + .addDuration("pickupTime", pickupTime, DEFAULT.pickupTime) .addObj("pickupCost", pickupCost, DEFAULT.pickupCost) - .addDurationSec("dropoffTime", dropoffTime, DEFAULT.dropoffTime) - .addObj("dropoffCost", dropoffCost, DEFAULT.dropoffCost) + .addDuration("dropOffTime", dropOffTime, DEFAULT.dropOffTime) + .addObj("dropOffCost", dropOffCost, DEFAULT.dropOffCost) .addBoolIfTrue("useAvailabilityInformation", useAvailabilityInformation) - .addNum( + .addObj( "arrivingInRentalVehicleAtDestinationCost", arrivingInRentalVehicleAtDestinationCost, DEFAULT.arrivingInRentalVehicleAtDestinationCost @@ -186,20 +185,20 @@ public static class Builder { private final VehicleRentalPreferences original; private int pickupTime; private Cost pickupCost; - private int dropoffTime; - private Cost dropoffCost; + private int dropOffTime; + private Cost dropOffCost; private boolean useAvailabilityInformation; - private double arrivingInRentalVehicleAtDestinationCost; + private Cost arrivingInRentalVehicleAtDestinationCost; private boolean allowArrivingInRentedVehicleAtDestination; private Set allowedNetworks; private Set bannedNetworks; private Builder(VehicleRentalPreferences original) { this.original = original; - this.pickupTime = Units.duration(original.pickupTime); + this.pickupTime = (int) original.pickupTime.toSeconds(); this.pickupCost = original.pickupCost; - this.dropoffTime = Units.duration(original.dropoffTime); - this.dropoffCost = original.dropoffCost; + this.dropOffTime = (int) original.dropOffTime.toSeconds(); + this.dropOffCost = original.dropOffCost; this.useAvailabilityInformation = original.useAvailabilityInformation; this.arrivingInRentalVehicleAtDestinationCost = original.arrivingInRentalVehicleAtDestinationCost; @@ -218,18 +217,28 @@ public Builder withPickupTime(int pickupTime) { return this; } + public Builder withPickupTime(Duration pickupTime) { + this.pickupTime = (int) pickupTime.toSeconds(); + return this; + } + public Builder withPickupCost(int pickupCost) { this.pickupCost = Cost.costOfSeconds(pickupCost); return this; } - public Builder withDropoffTime(int dropoffTime) { - this.dropoffTime = dropoffTime; + public Builder withDropOffTime(int dropOffTime) { + this.dropOffTime = dropOffTime; return this; } - public Builder withDropoffCost(int dropoffCost) { - this.dropoffCost = Cost.costOfSeconds(dropoffCost); + public Builder withDropOffTime(Duration dropOffTime) { + this.dropOffTime = (int) dropOffTime.toSeconds(); + return this; + } + + public Builder withDropOffCost(int dropOffCost) { + this.dropOffCost = Cost.costOfSeconds(dropOffCost); return this; } @@ -239,9 +248,10 @@ public Builder withUseAvailabilityInformation(boolean useAvailabilityInformation } public Builder withArrivingInRentalVehicleAtDestinationCost( - double arrivingInRentalVehicleAtDestinationCost + int arrivingInRentalVehicleAtDestinationCost ) { - this.arrivingInRentalVehicleAtDestinationCost = arrivingInRentalVehicleAtDestinationCost; + this.arrivingInRentalVehicleAtDestinationCost = + Cost.costOfSeconds(arrivingInRentalVehicleAtDestinationCost); return this; } diff --git a/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java b/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java index 66665f73b54..dc9fed8b9a3 100644 --- a/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java +++ b/src/main/java/org/opentripplanner/service/vehiclerental/street/VehicleRentalEdge.java @@ -161,8 +161,14 @@ public State[] traverse(State s0) { } } - s1.incrementWeight(pickedUp ? preferences.pickupCost() : preferences.dropoffCost()); - s1.incrementTimeInSeconds(pickedUp ? preferences.pickupTime() : preferences.dropoffTime()); + s1.incrementWeight( + pickedUp ? preferences.pickupCost().toSeconds() : preferences.dropOffCost().toSeconds() + ); + s1.incrementTimeInSeconds( + pickedUp + ? (int) preferences.pickupTime().toSeconds() + : (int) preferences.dropOffTime().toSeconds() + ); s1.setBackMode(null); return s1.makeStateArray(); } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index f15f6acdfe1..fab5262988b 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -586,15 +586,6 @@ private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder buil ) .asDouble(dft.reluctance()) ) - .withDropoffTime( - cc - .of("dropoffTime") - .since(V2_0) - .summary( - "Time to park a car in a park and ride, w/o taking into account driving and walking cost." - ) - .asInt(dft.dropoffTime()) - ) .withPickupCost( cc .of("pickupCost") diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java index 3d1534f5753..f862e9b9628 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java @@ -13,25 +13,33 @@ public class VehicleRentalConfig { static void mapRentalPreferences(NodeAdapter c, VehicleRentalPreferences.Builder builder) { var dft = builder.original(); builder - .withDropoffCost( + .withDropOffCost( c .of("dropOffCost") .since(V2_0) .summary("Cost to drop-off a rented vehicle.") - .asInt(dft.dropoffCost()) + .asInt(dft.dropOffCost().toSeconds()) ) - .withDropoffTime( + .withDropOffTime( c .of("dropOffTime") .since(V2_0) .summary("Time to drop-off a rented vehicle.") - .asInt(dft.dropoffTime()) + .asDuration(dft.dropOffTime()) ) .withPickupCost( - c.of("pickupCost").since(V2_0).summary("Cost to rent a vehicle.").asInt(dft.pickupCost()) + c + .of("pickupCost") + .since(V2_0) + .summary("Cost to rent a vehicle.") + .asInt(dft.pickupCost().toSeconds()) ) .withPickupTime( - c.of("pickupTime").since(V2_0).summary("Time to rent a vehicle.").asInt(dft.pickupTime()) + c + .of("pickupTime") + .since(V2_0) + .summary("Time to rent a vehicle.") + .asDuration(dft.pickupTime()) ) .withUseAvailabilityInformation( c @@ -49,7 +57,7 @@ static void mapRentalPreferences(NodeAdapter c, VehicleRentalPreferences.Builder .summary( "The cost of arriving at the destination with the rented vehicle, to discourage doing so." ) - .asDouble(dft.arrivingInRentalVehicleAtDestinationCost()) + .asInt(dft.arrivingInRentalVehicleAtDestinationCost().toSeconds()) ) .withAllowArrivingInRentedVehicleAtDestination( c diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java b/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java index 926eebc31d9..df5b24a5928 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java @@ -143,7 +143,7 @@ private State[] buildState(State s0, StateEditor s1, RoutingPreferences pref) { s0.mayKeepRentedVehicleAtDestination() && rentalPreferences.allowArrivingInRentedVehicleAtDestination() ) { - s1.incrementWeight(rentalPreferences.arrivingInRentalVehicleAtDestinationCost()); + s1.incrementWeight(rentalPreferences.arrivingInRentalVehicleAtDestinationCost().toSeconds()); } s1.setBackMode(null); diff --git a/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java b/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java index 011d0fec7f1..d825a8fcbea 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/TemporaryFreeEdge.java @@ -48,7 +48,7 @@ public State[] traverse(State s0) { s0.mayKeepRentedVehicleAtDestination() && rentalPreferences.allowArrivingInRentedVehicleAtDestination() ) { - s1.incrementWeight(rentalPreferences.arrivingInRentalVehicleAtDestinationCost()); + s1.incrementWeight(rentalPreferences.arrivingInRentalVehicleAtDestinationCost().toSeconds()); } return s1.makeStateArray(); diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java index 9bf287737df..4591d689f6c 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java @@ -91,10 +91,6 @@ void testToString() { "speed: 2.0, " + "reluctance: 1.2, " + "boardCost: $660, " + - "walkingSpeed: 1.15, " + - "walkingReluctance: 1.45, " + - "switchTime: 3m20s, " + - "switchCost: $450, " + "parking: VehicleParkingPreferences{parkCost: $30}, " + "rental: VehicleRentalPreferences{pickupTime: 30s}, " + "optimizeType: TRIANGLE, " + diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java index c81cb41d883..a21dfadbed0 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java @@ -16,7 +16,6 @@ class CarPreferencesTest { private static final int PICKUP_COST = 500; private static final double ACCELERATION_SPEED = 3.1; private static final double DECELERATION_SPEED = 3.5; - public static final int DROPOFF_TIME = 450; public static final int RENTAL_PICKUP_TIME = 30; public static final int PARK_COST = 30; @@ -26,7 +25,6 @@ class CarPreferencesTest { .withReluctance(RELUCTANCE) .withPickupTime(PICKUP_TIME) .withPickupCost(PICKUP_COST) - .withDropoffTime(DROPOFF_TIME) .withAccelerationSpeed(ACCELERATION_SPEED) .withDecelerationSpeed(DECELERATION_SPEED) .withRental(rental -> rental.withPickupTime(RENTAL_PICKUP_TIME).build()) @@ -53,11 +51,6 @@ void pickupCost() { assertEquals(PICKUP_COST, subject.pickupCost()); } - @Test - void dropoffTime() { - assertEquals(DROPOFF_TIME, subject.dropoffTime()); - } - @Test void accelerationSpeed() { assertEquals(ACCELERATION_SPEED, subject.accelerationSpeed()); @@ -103,7 +96,6 @@ void testToString() { "rental: VehicleRentalPreferences{pickupTime: 30s}, " + "pickupTime: 600, " + "pickupCost: $500, " + - "dropoffTime: 450, " + "accelerationSpeed: 3.1, decelerationSpeed: 3.5" + "}", subject.toString() diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java index 6092c8139bc..1b7068d0cd4 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleRentalPreferencesTest.java @@ -4,8 +4,10 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.opentripplanner.routing.api.request.preference.ImmutablePreferencesAsserts.assertEqualsAndHashCode; +import java.time.Duration; import java.util.Set; import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.model.Cost; class VehicleRentalPreferencesTest { @@ -23,8 +25,8 @@ class VehicleRentalPreferencesTest { .of() .withPickupTime(PICKUP_TIME) .withPickupCost(PICKUP_COST) - .withDropoffTime(DROPOFF_TIME) - .withDropoffCost(DROPOFF_COST) + .withDropOffTime(DROPOFF_TIME) + .withDropOffCost(DROPOFF_COST) .withArrivingInRentalVehicleAtDestinationCost(ARRIVE_IN_RENTAL_COST) .withUseAvailabilityInformation(USE_AVAILABILITY_INFORMATION) .withAllowArrivingInRentedVehicleAtDestination(ALLOW_ARRIVING_IN_RENTED_VEHICLE) @@ -34,22 +36,22 @@ class VehicleRentalPreferencesTest { @Test void pickupTime() { - assertEquals(PICKUP_TIME, subject.pickupTime()); + assertEquals(Duration.ofSeconds(PICKUP_TIME), subject.pickupTime()); } @Test void pickupCost() { - assertEquals(PICKUP_COST, subject.pickupCost()); + assertEquals(Cost.costOfSeconds(PICKUP_COST), subject.pickupCost()); } @Test void dropoffTime() { - assertEquals(DROPOFF_TIME, subject.dropoffTime()); + assertEquals(Duration.ofSeconds(DROPOFF_TIME), subject.dropOffTime()); } @Test void dropoffCost() { - assertEquals(DROPOFF_COST, subject.dropoffCost()); + assertEquals(Cost.costOfSeconds(DROPOFF_COST), subject.dropOffCost()); } @Test @@ -59,7 +61,10 @@ void useAvailabilityInformation() { @Test void arrivingInRentalVehicleAtDestinationCost() { - assertEquals(ARRIVE_IN_RENTAL_COST, subject.arrivingInRentalVehicleAtDestinationCost()); + assertEquals( + Cost.costOfSeconds(ARRIVE_IN_RENTAL_COST), + subject.arrivingInRentalVehicleAtDestinationCost() + ); } @Test @@ -102,10 +107,10 @@ void testToString() { "VehicleRentalPreferences{" + "pickupTime: 25s, " + "pickupCost: $250, " + - "dropoffTime: 45s, " + - "dropoffCost: $450, " + + "dropOffTime: 45s, " + + "dropOffCost: $450, " + "useAvailabilityInformation, " + - "arrivingInRentalVehicleAtDestinationCost: 500.0, " + + "arrivingInRentalVehicleAtDestinationCost: $500, " + "allowArrivingInRentedVehicleAtDestination, " + "allowedNetworks: [foo], " + "bannedNetworks: [bar]" + diff --git a/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java b/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java index 0694a991069..8dc1e240392 100644 --- a/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java +++ b/src/test/java/org/opentripplanner/street/integration/BikeRentalTest.java @@ -620,7 +620,7 @@ private List runStreetSearchAndCreateDescriptor( request.withPreferences(preferences -> preferences.withBike(bike -> bike.withRental(rental -> - rental.withPickupTime(42).withPickupCost(62).withDropoffCost(33).withDropoffTime(15) + rental.withPickupTime(42).withPickupCost(62).withDropOffCost(33).withDropOffTime(15) ) ) ); diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 996505b5296..c3b99284dbd 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -29,7 +29,7 @@ }, "rental": { "pickupCost": 120, - "dropOffTime": 30, + "dropOffTime": "30s", "dropOffCost": 30 }, "parking": { @@ -40,12 +40,11 @@ "car": { "speed": 40, "reluctance": 10, - "dropoffTime": 120, "decelerationSpeed": 2.9, "accelerationSpeed": 2.9, "rental": { "pickupCost": 120, - "dropOffTime": 30, + "dropOffTime": "30s", "dropOffCost": 30 } }, From 3bbe2d05ed14071e02536f04ed05177e6b9d9614 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 2 Jan 2024 14:34:43 +0200 Subject: [PATCH 06/21] Retype pickupTime and expose cost as Cost --- docs/RouteRequest.md | 2 +- .../request/preference/CarPreferences.java | 23 ++++++++++--------- .../routerequest/RouteRequestConfig.java | 4 ++-- .../street/model/edge/CarPickupableEdge.java | 8 +++---- .../preference/CarPreferencesTest.java | 10 ++++---- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index aff3f3e5758..f682eedcaa7 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -85,7 +85,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    accelerationSpeed | `double` | The acceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | |    decelerationSpeed | `double` | The deceleration speed of an automobile, in meters per second per second. | *Optional* | `2.9` | 2.0 | |    pickupCost | `integer` | Add a cost for car pickup changes when a pickup or drop off takes place | *Optional* | `120` | 2.1 | -|    pickupTime | `integer` | Add a time for car pickup changes when a pickup or drop off takes place | *Optional* | `60` | 2.1 | +|    pickupTime | `duration` | Add a time for car pickup changes when a pickup or drop off takes place | *Optional* | `"PT1M"` | 2.1 | |    reluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | |    speed | `double` | Max car speed along streets, in meters per second | *Optional* | `40.0` | 2.0 | |    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java index 9615a586335..b2f226cf307 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/CarPreferences.java @@ -3,6 +3,7 @@ import static org.opentripplanner.framework.lang.ObjectUtils.ifNotNull; import java.io.Serializable; +import java.time.Duration; import java.util.Objects; import java.util.function.Consumer; import org.opentripplanner.framework.lang.DoubleUtils; @@ -25,7 +26,7 @@ public final class CarPreferences implements Serializable { private final double reluctance; private final VehicleParkingPreferences parking; private final VehicleRentalPreferences rental; - private final int pickupTime; + private final Duration pickupTime; private final Cost pickupCost; private final double accelerationSpeed; private final double decelerationSpeed; @@ -36,7 +37,7 @@ private CarPreferences() { this.reluctance = 2.0; this.parking = VehicleParkingPreferences.DEFAULT; this.rental = VehicleRentalPreferences.DEFAULT; - this.pickupTime = 60; + this.pickupTime = Duration.ofMinutes(1); this.pickupCost = Cost.costOfMinutes(2); this.accelerationSpeed = 2.9; this.decelerationSpeed = 2.9; @@ -47,7 +48,7 @@ private CarPreferences(Builder builder) { this.reluctance = Units.reluctance(builder.reluctance); this.parking = builder.parking; this.rental = builder.rental; - this.pickupTime = Units.duration(builder.pickupTime); + this.pickupTime = Duration.ofSeconds(Units.duration(builder.pickupTime)); this.pickupCost = builder.pickupCost; this.accelerationSpeed = Units.acceleration(builder.accelerationSpeed); this.decelerationSpeed = Units.acceleration(builder.decelerationSpeed); @@ -85,13 +86,13 @@ public VehicleRentalPreferences rental() { } /** Time of getting in/out of a carPickup (taxi) */ - public int pickupTime() { + public Duration pickupTime() { return pickupTime; } /** Cost of getting in/out of a carPickup (taxi) */ - public int pickupCost() { - return pickupCost.toSeconds(); + public Cost pickupCost() { + return pickupCost; } /** @@ -120,7 +121,7 @@ public boolean equals(Object o) { DoubleUtils.doubleEquals(that.reluctance, reluctance) && parking.equals(that.parking) && rental.equals(that.rental) && - pickupTime == that.pickupTime && + Objects.equals(pickupTime, that.pickupTime) && pickupCost.equals(that.pickupCost) && DoubleUtils.doubleEquals(that.accelerationSpeed, accelerationSpeed) && DoubleUtils.doubleEquals(that.decelerationSpeed, decelerationSpeed) @@ -149,7 +150,7 @@ public String toString() { .addNum("reluctance", reluctance, DEFAULT.reluctance) .addObj("parking", parking, DEFAULT.parking) .addObj("rental", rental, DEFAULT.rental) - .addNum("pickupTime", pickupTime, DEFAULT.pickupTime) + .addObj("pickupTime", pickupTime, DEFAULT.pickupTime) .addObj("pickupCost", pickupCost, DEFAULT.pickupCost) .addNum("accelerationSpeed", accelerationSpeed, DEFAULT.accelerationSpeed) .addNum("decelerationSpeed", decelerationSpeed, DEFAULT.decelerationSpeed) @@ -175,7 +176,7 @@ public Builder(CarPreferences original) { this.reluctance = original.reluctance; this.parking = original.parking; this.rental = original.rental; - this.pickupTime = original.pickupTime; + this.pickupTime = (int) original.pickupTime.toSeconds(); this.pickupCost = original.pickupCost; this.accelerationSpeed = original.accelerationSpeed; this.decelerationSpeed = original.decelerationSpeed; @@ -205,8 +206,8 @@ public Builder withRental(Consumer body) { return this; } - public Builder withPickupTime(int pickupTime) { - this.pickupTime = pickupTime; + public Builder withPickupTime(Duration pickupTime) { + this.pickupTime = (int) pickupTime.toSeconds(); return this; } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index fab5262988b..1e4f1e860c4 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -591,14 +591,14 @@ private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder buil .of("pickupCost") .since(V2_1) .summary("Add a cost for car pickup changes when a pickup or drop off takes place") - .asInt(dft.pickupCost()) + .asInt(dft.pickupCost().toSeconds()) ) .withPickupTime( cc .of("pickupTime") .since(V2_1) .summary("Add a time for car pickup changes when a pickup or drop off takes place") - .asInt(dft.pickupTime()) + .asDuration(dft.pickupTime()) ) .withAccelerationSpeed( cc diff --git a/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java b/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java index ec50e3b60ca..7ea1678bbe7 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/CarPickupableEdge.java @@ -30,13 +30,13 @@ default void dropOffAfterDriving(State state, StateEditor editor) { ? CarPickupState.WALK_TO_PICKUP : CarPickupState.WALK_FROM_DROP_OFF ); - editor.incrementTimeInSeconds(state.getPreferences().car().pickupTime()); - editor.incrementWeight(state.getPreferences().car().pickupCost()); + editor.incrementTimeInSeconds((int) state.getPreferences().car().pickupTime().toSeconds()); + editor.incrementWeight(state.getPreferences().car().pickupCost().toSeconds()); } default void driveAfterPickup(State state, StateEditor editor) { editor.setCarPickupState(CarPickupState.IN_CAR); - editor.incrementTimeInSeconds(state.getPreferences().car().pickupTime()); - editor.incrementWeight(state.getPreferences().car().pickupCost()); + editor.incrementTimeInSeconds((int) state.getPreferences().car().pickupTime().toSeconds()); + editor.incrementWeight(state.getPreferences().car().pickupCost().toSeconds()); } } diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java index a21dfadbed0..3c0a294d7e2 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java @@ -4,7 +4,9 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.opentripplanner.routing.api.request.preference.ImmutablePreferencesAsserts.assertEqualsAndHashCode; +import java.time.Duration; import org.junit.jupiter.api.Test; +import org.opentripplanner.framework.model.Cost; class CarPreferencesTest { @@ -23,7 +25,7 @@ class CarPreferencesTest { .of() .withSpeed(SPEED) .withReluctance(RELUCTANCE) - .withPickupTime(PICKUP_TIME) + .withPickupTime(Duration.ofSeconds(PICKUP_TIME)) .withPickupCost(PICKUP_COST) .withAccelerationSpeed(ACCELERATION_SPEED) .withDecelerationSpeed(DECELERATION_SPEED) @@ -43,12 +45,12 @@ void reluctance() { @Test void pickupTime() { - assertEquals(PICKUP_TIME, subject.pickupTime()); + assertEquals(Duration.ofSeconds(PICKUP_TIME), subject.pickupTime()); } @Test void pickupCost() { - assertEquals(PICKUP_COST, subject.pickupCost()); + assertEquals(Cost.costOfSeconds(PICKUP_COST), subject.pickupCost()); } @Test @@ -94,7 +96,7 @@ void testToString() { "reluctance: 5.1, " + "parking: VehicleParkingPreferences{parkCost: $30}, " + "rental: VehicleRentalPreferences{pickupTime: 30s}, " + - "pickupTime: 600, " + + "pickupTime: PT10M, " + "pickupCost: $500, " + "accelerationSpeed: 3.1, decelerationSpeed: 3.5" + "}", From 4009ade94fb5b4cf1fcea30f8c1f30a32bdef4c4 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 2 Jan 2024 15:10:15 +0200 Subject: [PATCH 07/21] Add car parking to doc --- docs/RouteRequest.md | 49 +++++++++++++++++++ docs/RouterConfiguration.md | 4 ++ .../standalone/config/router-config.json | 4 ++ 3 files changed, 57 insertions(+) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index f682eedcaa7..f16a4996ffe 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -89,6 +89,12 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    reluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | |    speed | `double` | Max car speed along streets, in meters per second | *Optional* | `40.0` | 2.0 | |    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | +|       parkCost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | +|       parkTime | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       [unpreferredVehicleParkingTagCost](#rd_car_parking_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | +|       [bannedVehicleParkingTags](#rd_car_parking_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | +|       [preferredVehicleParkingTags](#rd_car_parking_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | +|       [requiredVehicleParkingTags](#rd_car_parking_requiredVehicleParkingTags) | `string[]` | Tags without which a vehicle parking will not be used. If empty, no tags are required. | *Optional* | | 2.1 | |    rental | `object` | Vehicle rental options | *Optional* | | 2.3 | |       allowKeepingAtDestination | `boolean` | If a vehicle should be allowed to be kept at the end of a station-based rental. | *Optional* | `false` | 2.2 | |       dropOffCost | `integer` | Cost to drop-off a rented vehicle. | *Optional* | `30` | 2.0 | @@ -528,6 +534,45 @@ Sometimes there is a need to configure a board times for specific modes, such as ferries, where the check-in process needs to be done in good time before ride. +

unpreferredVehicleParkingTagCost

+ +**Since version:** `2.3` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `300` +**Path:** /routingDefaults/car/parking + +What cost to add if a parking facility doesn't contain a preferred tag. + +See `preferredVehicleParkingTags`. + +

bannedVehicleParkingTags

+ +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/car/parking + +Tags with which a vehicle parking will not be used. If empty, no tags are banned. + +Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + + +

preferredVehicleParkingTags

+ +**Since version:** `2.3` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/car/parking + +Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. + +Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + + +

requiredVehicleParkingTags

+ +**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/car/parking + +Tags without which a vehicle parking will not be used. If empty, no tags are required. + +Vehicle parking tags can originate from different places depending on the origin of the parking(OSM or RT feed). + +

allowedNetworks

**Since version:** `2.1` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional` @@ -1014,6 +1059,10 @@ include stairs as a last result. "pickupCost" : 120, "dropOffTime" : "30s", "dropOffCost" : 30 + }, + "parking" : { + "parkTime" : "5m", + "parkCost" : 600 } }, "walk" : { diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index af2c0a9630a..9c794b3086d 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -485,6 +485,10 @@ Used to group requests when monitoring OTP. "pickupCost" : 120, "dropOffTime" : "30s", "dropOffCost" : 30 + }, + "parking" : { + "parkTime" : "5m", + "parkCost" : 600 } }, "walk" : { diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index c3b99284dbd..8dfb1434ce4 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -46,6 +46,10 @@ "pickupCost": 120, "dropOffTime": "30s", "dropOffCost": 30 + }, + "parking": { + "parkTime": "5m", + "parkCost": 600 } }, "walk": { From 27d49214f488efdb9d37564ea8d9b85d71621247 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 2 Jan 2024 16:41:25 +0200 Subject: [PATCH 08/21] Expose triangle in docs --- docs/RouteRequest.md | 19 +++++++++++++++++++ docs/RouterConfiguration.md | 5 +++++ .../standalone/config/router-config.json | 5 +++++ 3 files changed, 29 insertions(+) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index f16a4996ffe..4f52149aad1 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -74,6 +74,9 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       [allowedNetworks](#rd_bicycle_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | |       [bannedNetworks](#rd_bicycle_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | |    triangle | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | +|       flatness | `double` | Relative importance of flat terrain (range 0-1). | *Optional* | `0.0` | 2.0 | +|       [safety](#rd_bicycle_triangle_safety) | `double` | Relative importance of safety (range 0-1). | *Optional* | `0.0` | 2.0 | +|       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | |    walk | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | |       [hopCost](#rd_bicycle_walk_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | |       [hopTime](#rd_bicycle_walk_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle in seconds. | *Optional* | `"PT0S"` | 2.0 | @@ -500,6 +503,17 @@ The vehicle rental networks which may be used. If empty all networks may be used The vehicle rental networks which may not be used. If empty, no networks are banned. +

safety

+ +**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.0` +**Path:** /routingDefaults/bicycle/triangle + +Relative importance of safety (range 0-1). + +This factor can also include other concerns such as convenience and general cyclist +preferences by taking into account road surface etc. + +

hopCost

**Since version:** `2.0` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0` @@ -1048,6 +1062,11 @@ include stairs as a last result. "parking" : { "parkTime" : "1m", "parkCost" : 120 + }, + "triangle" : { + "safety" : 0.4, + "flatness" : 0.3, + "time" : 0.3 } }, "car" : { diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index 9c794b3086d..f49a5bf9745 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -474,6 +474,11 @@ Used to group requests when monitoring OTP. "parking" : { "parkTime" : "1m", "parkCost" : 120 + }, + "triangle" : { + "safety" : 0.4, + "flatness" : 0.3, + "time" : 0.3 } }, "car" : { diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 8dfb1434ce4..9f6b336fde5 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -35,6 +35,11 @@ "parking": { "parkTime": "1m", "parkCost": 120 + }, + "triangle": { + "safety": 0.4, + "flatness": 0.3, + "time": 0.3 } }, "car": { From 831a4d8605a97d112111633ff848fd60679a6272 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Thu, 4 Jan 2024 11:22:11 +0200 Subject: [PATCH 09/21] Rename bicycle optimization types in the internal model and ease triangle configuration --- docs/RouteRequest.md | 19 +++++++++++---- .../common/RequestToPreferencesMapper.java | 9 ++++--- .../api/common/RoutingResource.java | 4 ++-- .../mapping/LegacyBicycleOptimizeType.java | 24 +++++++++++++++++++ .../gtfs/mapping/OptimizationTypeMapper.java | 19 +++++++++++++++ .../apis/gtfs/mapping/RouteRequestMapper.java | 7 +++++- .../apis/transmodel/model/EnumTypes.java | 8 +++---- .../request/preference/BikePreferences.java | 17 +++++++++++-- .../preference/TimeSlopeSafetyTriangle.java | 8 +++++++ .../routing/core/BicycleOptimizeType.java | 12 ++++++---- .../routerequest/RouteRequestConfig.java | 6 ++++- .../TriangleOptimizationConfig.java | 1 + .../street/model/edge/StreetEdge.java | 14 +++++------ .../visualizer/GraphVisualizer.java | 10 ++++---- .../gtfs/mapping/RouteRequestMapperTest.java | 17 ++++++------- .../mapping/TripRequestMapperTest.java | 2 +- .../preference/BikePreferencesTest.java | 23 ++++++++++++++++++ .../integration/BicycleRoutingTest.java | 4 +++- 18 files changed, 161 insertions(+), 43 deletions(-) create mode 100644 src/main/java/org/opentripplanner/api/mapping/LegacyBicycleOptimizeType.java create mode 100644 src/main/java/org/opentripplanner/apis/gtfs/mapping/OptimizationTypeMapper.java diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 4f52149aad1..b95c58ec32f 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -53,7 +53,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe | [alightSlackForMode](#rd_alightSlackForMode) | `enum map of duration` | How much extra time should be given when alighting a vehicle for each given mode. | *Optional* | | 2.0 | | bicycle | `object` | Bicycle preferences. | *Optional* | | 2.5 | |    [boardCost](#rd_bicycle_boardCost) | `integer` | Prevents unnecessary transfers by adding a cost for boarding a transit vehicle. | *Optional* | `600` | 2.0 | -|    [optimization](#rd_bicycle_optimization) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe"` | 2.0 | +|    [optimization](#rd_bicycle_optimization) | `enum` | The set of characteristics that the user wants to optimize for. | *Optional* | `"safe-streets"` | 2.0 | |    reluctance | `double` | A multiplier for how bad cycling is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | |    speed | `double` | Max bicycle speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | |    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | @@ -73,7 +73,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       useAvailabilityInformation | `boolean` | Whether or not vehicle rental availability information will be used to plan vehicle rental trips. | *Optional* | `false` | 2.0 | |       [allowedNetworks](#rd_bicycle_rental_allowedNetworks) | `string[]` | The vehicle rental networks which may be used. If empty all networks may be used. | *Optional* | | 2.1 | |       [bannedNetworks](#rd_bicycle_rental_bannedNetworks) | `string[]` | The vehicle rental networks which may not be used. If empty, no networks are banned. | *Optional* | | 2.1 | -|    triangle | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | +|    [triangle](#rd_bicycle_triangle) | `object` | Triangle optimization criteria. | *Optional* | | 2.5 | |       flatness | `double` | Relative importance of flat terrain (range 0-1). | *Optional* | `0.0` | 2.0 | |       [safety](#rd_bicycle_triangle_safety) | `double` | Relative importance of safety (range 0-1). | *Optional* | `0.0` | 2.0 | |       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | @@ -444,12 +444,14 @@ This is the cost that is used when boarding while cycling.This is usually higher

optimization

-**Since version:** `2.0` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"safe"` +**Since version:** `2.0` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"safe-streets"` **Path:** /routingDefaults/bicycle -**Enum values:** `quick` | `safe` | `flat` | `greenways` | `triangle` +**Enum values:** `shortest-duration` | `safe-streets` | `flat-streets` | `safest-streets` | `triangle` The set of characteristics that the user wants to optimize for. +If the triangle optimization is used, it's enough to just define the triangle parameters +

unpreferredVehicleParkingTagCost

**Since version:** `2.3` ∙ **Type:** `integer` ∙ **Cardinality:** `Optional` ∙ **Default value:** `300` @@ -503,6 +505,15 @@ The vehicle rental networks which may be used. If empty all networks may be used The vehicle rental networks which may not be used. If empty, no networks are banned. +

triangle

+ +**Since version:** `2.5` ∙ **Type:** `object` ∙ **Cardinality:** `Optional` +**Path:** /routingDefaults/bicycle + +Triangle optimization criteria. + +Optimization type doesn't need to be defined if these values are defined. +

safety

**Since version:** `2.0` ∙ **Type:** `double` ∙ **Cardinality:** `Optional` ∙ **Default value:** `0.0` diff --git a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java index 5da43e9a179..e4878e6c7d9 100644 --- a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java @@ -2,6 +2,7 @@ import jakarta.validation.constraints.NotNull; import java.util.function.Consumer; +import org.opentripplanner.api.mapping.LegacyBicycleOptimizeType; import org.opentripplanner.framework.lang.ObjectUtils; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; @@ -10,7 +11,6 @@ import org.opentripplanner.routing.api.request.preference.RoutingPreferences; import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; import org.opentripplanner.routing.api.request.preference.VehicleRentalPreferences; -import org.opentripplanner.routing.core.BicycleOptimizeType; class RequestToPreferencesMapper { @@ -67,9 +67,12 @@ private void mapBike() { setIfNotNull(req.bikeSpeed, bike::withSpeed); setIfNotNull(req.bikeReluctance, bike::withReluctance); setIfNotNull(req.bikeBoardCost, bike::withBoardCost); - setIfNotNull(req.bikeOptimizeType, bike::withOptimizeType); + setIfNotNull( + req.bikeOptimizeType, + optimizeType -> bike.withOptimizeType(LegacyBicycleOptimizeType.map(optimizeType)) + ); - if (req.bikeOptimizeType == BicycleOptimizeType.TRIANGLE) { + if (req.bikeOptimizeType == LegacyBicycleOptimizeType.TRIANGLE) { bike.withOptimizeTriangle(triangle -> { setIfNotNull(req.triangleTimeFactor, triangle::withTime); setIfNotNull(req.triangleSlopeFactor, triangle::withSlope); diff --git a/src/main/java/org/opentripplanner/api/common/RoutingResource.java b/src/main/java/org/opentripplanner/api/common/RoutingResource.java index 8e7501c77fd..374e5515e3d 100644 --- a/src/main/java/org/opentripplanner/api/common/RoutingResource.java +++ b/src/main/java/org/opentripplanner/api/common/RoutingResource.java @@ -18,6 +18,7 @@ import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; +import org.opentripplanner.api.mapping.LegacyBicycleOptimizeType; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.ext.dataoverlay.api.DataOverlayParameters; import org.opentripplanner.framework.application.OTPFeature; @@ -27,7 +28,6 @@ import org.opentripplanner.routing.api.request.preference.ItineraryFilterDebugProfile; import org.opentripplanner.routing.api.request.request.filter.SelectRequest; import org.opentripplanner.routing.api.request.request.filter.TransitFilterRequest; -import org.opentripplanner.routing.core.BicycleOptimizeType; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.standalone.config.framework.file.ConfigFileLoader; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; @@ -248,7 +248,7 @@ public abstract class RoutingResource { */ @Deprecated @QueryParam("optimize") - protected BicycleOptimizeType bikeOptimizeType; + protected LegacyBicycleOptimizeType bikeOptimizeType; /** * The set of modes that a user is willing to use, with qualifiers stating whether vehicles should diff --git a/src/main/java/org/opentripplanner/api/mapping/LegacyBicycleOptimizeType.java b/src/main/java/org/opentripplanner/api/mapping/LegacyBicycleOptimizeType.java new file mode 100644 index 00000000000..1cc262ad720 --- /dev/null +++ b/src/main/java/org/opentripplanner/api/mapping/LegacyBicycleOptimizeType.java @@ -0,0 +1,24 @@ +package org.opentripplanner.api.mapping; + +import org.opentripplanner.routing.core.BicycleOptimizeType; + +/** + * Bicycle optimization types that are only meant to be used by the REST API. Related to {@link org.opentripplanner.routing.core.BicycleOptimizeType} + */ +public enum LegacyBicycleOptimizeType { + QUICK, + SAFE, + FLAT, + GREENWAYS, + TRIANGLE; + + public static BicycleOptimizeType map(LegacyBicycleOptimizeType type) { + return switch (type) { + case QUICK -> BicycleOptimizeType.SHORTEST_DURATION; + case FLAT -> BicycleOptimizeType.FLAT_STREETS; + case SAFE -> BicycleOptimizeType.SAFE_STREETS; + case GREENWAYS -> BicycleOptimizeType.SAFEST_STREETS; + case TRIANGLE -> BicycleOptimizeType.TRIANGLE; + }; + } +} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/OptimizationTypeMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/OptimizationTypeMapper.java new file mode 100644 index 00000000000..1f53652f7b7 --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/OptimizationTypeMapper.java @@ -0,0 +1,19 @@ +package org.opentripplanner.apis.gtfs.mapping; + +import javax.annotation.Nonnull; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.routing.core.BicycleOptimizeType; + +public final class OptimizationTypeMapper { + + @Nonnull + public static BicycleOptimizeType map(GraphQLTypes.GraphQLOptimizeType optimizeType) { + return switch (optimizeType) { + case QUICK -> BicycleOptimizeType.SHORTEST_DURATION; + case FLAT -> BicycleOptimizeType.FLAT_STREETS; + case SAFE -> BicycleOptimizeType.SAFE_STREETS; + case GREENWAYS -> BicycleOptimizeType.SAFEST_STREETS; + case TRIANGLE -> BicycleOptimizeType.TRIANGLE; + }; + } +} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java index a12ef45f6fb..13593a99e58 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapper.java @@ -16,6 +16,7 @@ import org.opentripplanner.api.parameter.QualifiedMode; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.framework.graphql.GraphQLUtils; import org.opentripplanner.model.GenericLocation; import org.opentripplanner.routing.api.request.RouteRequest; @@ -71,7 +72,11 @@ public static RouteRequest toRouteRequest( callWith.argument("bikeBoardCost", bike::withBoardCost); if (environment.getArgument("optimize") != null) { - bike.withOptimizeType(BicycleOptimizeType.valueOf(environment.getArgument("optimize"))); + bike.withOptimizeType( + OptimizationTypeMapper.map( + GraphQLTypes.GraphQLOptimizeType.valueOf(environment.getArgument("optimize")) + ) + ); } if (bike.optimizeType() == BicycleOptimizeType.TRIANGLE) { bike.withOptimizeTriangle(triangle -> { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java b/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java index 12aa19fbaea..e2897d868c9 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/EnumTypes.java @@ -64,10 +64,10 @@ public class EnumTypes { public static final GraphQLEnumType BICYCLE_OPTIMISATION_METHOD = GraphQLEnumType .newEnum() .name("BicycleOptimisationMethod") - .value("quick", BicycleOptimizeType.QUICK) - .value("safe", BicycleOptimizeType.SAFE) - .value("flat", BicycleOptimizeType.FLAT) - .value("greenways", BicycleOptimizeType.GREENWAYS) + .value("quick", BicycleOptimizeType.SHORTEST_DURATION) + .value("safe", BicycleOptimizeType.SAFE_STREETS) + .value("flat", BicycleOptimizeType.FLAT_STREETS) + .value("greenways", BicycleOptimizeType.SAFEST_STREETS) .value("triangle", BicycleOptimizeType.TRIANGLE) .build(); diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java index f282e02340c..2d887eba596 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java @@ -2,6 +2,8 @@ import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; import static org.opentripplanner.framework.lang.ObjectUtils.ifNotNull; +import static org.opentripplanner.routing.core.BicycleOptimizeType.SAFE_STREETS; +import static org.opentripplanner.routing.core.BicycleOptimizeType.TRIANGLE; import java.io.Serializable; import java.util.Objects; @@ -37,7 +39,7 @@ private BikePreferences() { this.boardCost = Cost.costOfMinutes(10); this.parking = VehicleParkingPreferences.DEFAULT; this.rental = VehicleRentalPreferences.DEFAULT; - this.optimizeType = BicycleOptimizeType.SAFE; + this.optimizeType = SAFE_STREETS; this.optimizeTriangle = TimeSlopeSafetyTriangle.DEFAULT; this.walking = VehicleWalkingPreferences.DEFAULT; } @@ -92,7 +94,7 @@ public VehicleRentalPreferences rental() { } /** - * The set of characteristics that the user wants to optimize for -- defaults to SAFE. + * The set of characteristics that the user wants to optimize for -- defaults to SAFE_STREETS. */ public BicycleOptimizeType optimizeType() { return optimizeType; @@ -233,6 +235,17 @@ public TimeSlopeSafetyTriangle optimizeTriangle() { return optimizeTriangle; } + /** This also sets the optimization type as TRIANGLE if triangle parameters are defined */ + public Builder withForcedOptimizeTriangle(Consumer body) { + var builder = TimeSlopeSafetyTriangle.of(); + body.accept(builder); + this.optimizeTriangle = builder.buildOrDefault(this.optimizeTriangle); + if (!builder.isEmpty()) { + this.optimizeType = TRIANGLE; + } + return this; + } + public Builder withOptimizeTriangle(Consumer body) { var builder = TimeSlopeSafetyTriangle.of(); body.accept(builder); diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java b/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java index b901d738213..99925a441fd 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/TimeSlopeSafetyTriangle.java @@ -1,5 +1,6 @@ package org.opentripplanner.routing.api.request.preference; +import static org.opentripplanner.framework.lang.DoubleUtils.doubleEquals; import static org.opentripplanner.framework.lang.DoubleUtils.roundTo2Decimals; /** @@ -109,6 +110,13 @@ public Builder withSafety(double safety) { return this; } + /** + * Returns true if none of the values are set (i.e. all values are zero). + */ + public boolean isEmpty() { + return doubleEquals(time, ZERO) && doubleEquals(slope, ZERO) && doubleEquals(safety, ZERO); + } + public TimeSlopeSafetyTriangle build() { return new TimeSlopeSafetyTriangle(time, slope, safety); } diff --git a/src/main/java/org/opentripplanner/routing/core/BicycleOptimizeType.java b/src/main/java/org/opentripplanner/routing/core/BicycleOptimizeType.java index b5a47af82de..1d639e0af8b 100644 --- a/src/main/java/org/opentripplanner/routing/core/BicycleOptimizeType.java +++ b/src/main/java/org/opentripplanner/routing/core/BicycleOptimizeType.java @@ -9,10 +9,14 @@ * combined presets of routing parameters, except for triangle. */ public enum BicycleOptimizeType { - QUICK,/* the fastest trip */ - SAFE, - FLAT,/* needs a rewrite */ - GREENWAYS, + /** This was previously called QUICK */ + SHORTEST_DURATION, + /** This was previously called SAFE */ + SAFE_STREETS, + /** This was previously called FLAT. Needs a rewrite. */ + FLAT_STREETS, + /** This was previously called GREENWAYS. */ + SAFEST_STREETS, TRIANGLE; private static final Set NON_TRIANGLE_VALUES = Collections.unmodifiableSet( diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 1e4f1e860c4..8aaa0b1d243 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -372,9 +372,13 @@ private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder bu .of("optimization") .since(V2_0) .summary("The set of characteristics that the user wants to optimize for.") + .description( + "If the triangle optimization is used, it's enough to just define the triangle parameters" + ) .asEnum(dft.optimizeType()) ) - .withOptimizeTriangle(it -> mapOptimizationTriangle(cb, it)) + // triangle overrides the optimization type if defined + .withForcedOptimizeTriangle(it -> mapOptimizationTriangle(cb, it)) .withWalking(it -> mapVehicleWalking(cb, it)) .withParking(it -> mapParking(cb, it)) .withRental(it -> mapRental(cb, it)); diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java index e4988b02767..361e591891c 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java @@ -47,6 +47,7 @@ static void mapOptimizationTriangle(NodeAdapter c, TimeSlopeSafetyTriangle.Build .of("triangle") .since(V2_5) .summary("Triangle optimization criteria.") + .description("Optimization type doesn't need to be defined if these values are defined.") .asObject(); mapTriangleParameters(optimizationTriangle, preferences); } diff --git a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java b/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java index 3f17081b6cb..1e3594ee04b 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java @@ -51,7 +51,7 @@ public class StreetEdge private static final Logger LOG = LoggerFactory.getLogger(StreetEdge.class); - private static final double GREENWAY_SAFETY_FACTOR = 0.1; + private static final double SAFEST_STREETS_SAFETY_FACTOR = 0.1; /** If you have more than 16 flags, increase flags to short or int */ static final int BACK_FLAG_INDEX = 0; @@ -1217,17 +1217,17 @@ private TraversalCosts bicycleTraversalCost(RoutingPreferences pref, double spee double time = getEffectiveBikeDistance() / speed; double weight; switch (pref.bike().optimizeType()) { - case GREENWAYS -> { + case SAFEST_STREETS -> { weight = bicycleSafetyFactor * getDistanceMeters() / speed; - if (bicycleSafetyFactor <= GREENWAY_SAFETY_FACTOR) { - // greenways are treated as even safer than they really are + if (bicycleSafetyFactor <= SAFEST_STREETS_SAFETY_FACTOR) { + // safest streets are treated as even safer than they really are weight *= 0.66; } } - case SAFE -> weight = getEffectiveBicycleSafetyDistance() / speed; - case FLAT -> /* see notes in StreetVertex on speed overhead */weight = + case SAFE_STREETS -> weight = getEffectiveBicycleSafetyDistance() / speed; + case FLAT_STREETS -> /* see notes in StreetVertex on speed overhead */weight = getEffectiveBikeDistanceForWorkCost() / speed; - case QUICK -> weight = getEffectiveBikeDistance() / speed; + case SHORTEST_DURATION -> weight = getEffectiveBikeDistance() / speed; case TRIANGLE -> { double quick = getEffectiveBikeDistance(); double safety = getEffectiveBicycleSafetyDistance(); diff --git a/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java b/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java index 73516b0348f..4154ee6362a 100644 --- a/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java +++ b/src/main/java/org/opentripplanner/visualizer/GraphVisualizer.java @@ -545,18 +545,18 @@ protected void route(String from, String to) { BicycleOptimizeType getSelectedOptimizeType() { if (opQuick.isSelected()) { - return BicycleOptimizeType.QUICK; + return BicycleOptimizeType.SHORTEST_DURATION; } if (opSafe.isSelected()) { - return BicycleOptimizeType.SAFE; + return BicycleOptimizeType.SAFE_STREETS; } if (opFlat.isSelected()) { - return BicycleOptimizeType.FLAT; + return BicycleOptimizeType.FLAT_STREETS; } if (opGreenways.isSelected()) { - return BicycleOptimizeType.GREENWAYS; + return BicycleOptimizeType.SAFEST_STREETS; } - return BicycleOptimizeType.QUICK; + return BicycleOptimizeType.SHORTEST_DURATION; } private Container makeDiffTab() { diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java b/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java index fba953cd93a..f52b81717d4 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java @@ -4,13 +4,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.params.provider.Arguments.of; -import static org.opentripplanner.routing.core.BicycleOptimizeType.SAFE; +import static org.opentripplanner.routing.core.BicycleOptimizeType.SAFE_STREETS; import static org.opentripplanner.routing.core.BicycleOptimizeType.TRIANGLE; import graphql.ExecutionInput; import graphql.execution.ExecutionId; import graphql.schema.DataFetchingEnvironment; import graphql.schema.DataFetchingEnvironmentImpl; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.Map; @@ -21,12 +22,12 @@ import org.opentripplanner._support.time.ZoneIds; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.TestRoutingService; +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.ext.fares.impl.DefaultFareService; import org.opentripplanner.model.plan.PlanTestConstants; import org.opentripplanner.routing.api.request.RouteRequest; import org.opentripplanner.routing.api.request.preference.TimeSlopeSafetyTriangle; import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; -import org.opentripplanner.routing.core.BicycleOptimizeType; import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.routing.graphfinder.GraphFinder; import org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService; @@ -149,7 +150,7 @@ private static Map mode(String mode) { void defaultBikeOptimize() { Map arguments = Map.of(); var routeRequest = RouteRequestMapper.toRouteRequest(executionContext(arguments), context); - assertEquals(SAFE, routeRequest.preferences().bike().optimizeType()); + assertEquals(SAFE_STREETS, routeRequest.preferences().bike().optimizeType()); } @Test @@ -170,14 +171,14 @@ void bikeTriangle() { ); } - static Stream noTriangleCases = BicycleOptimizeType - .nonTriangleValues() - .stream() + static Stream noTriangleCases = Arrays + .stream(GraphQLTypes.GraphQLOptimizeType.values()) + .filter(value -> value != GraphQLTypes.GraphQLOptimizeType.TRIANGLE) .map(Arguments::of); @ParameterizedTest @VariableSource("noTriangleCases") - void noTriangle(BicycleOptimizeType bot) { + void noTriangle(GraphQLTypes.GraphQLOptimizeType bot) { Map arguments = Map.of( "optimize", bot.name(), @@ -187,7 +188,7 @@ void noTriangle(BicycleOptimizeType bot) { var routeRequest = RouteRequestMapper.toRouteRequest(executionContext(arguments), context); - assertEquals(bot, routeRequest.preferences().bike().optimizeType()); + assertEquals(OptimizationTypeMapper.map(bot), routeRequest.preferences().bike().optimizeType()); assertEquals( TimeSlopeSafetyTriangle.DEFAULT, routeRequest.preferences().bike().optimizeTriangle() diff --git a/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java b/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java index 3058f622281..9a01a36cbcb 100644 --- a/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/transmodel/mapping/TripRequestMapperTest.java @@ -272,7 +272,7 @@ public void testBikeTriangleFactors() { @Test void testDefaultTriangleFactors() { var req2 = TripRequestMapper.createRequest(executionContext(Map.of())); - assertEquals(BicycleOptimizeType.SAFE, req2.preferences().bike().optimizeType()); + assertEquals(BicycleOptimizeType.SAFE_STREETS, req2.preferences().bike().optimizeType()); assertEquals(TimeSlopeSafetyTriangle.DEFAULT, req2.preferences().bike().optimizeTriangle()); } diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java index 4591d689f6c..a314aa48799 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java @@ -99,4 +99,27 @@ void testToString() { subject.toString() ); } + + @Test + void testForcedTriangleOptimization() { + var trianglePreferences = BikePreferences + .of() + .withForcedOptimizeTriangle(it -> it.withSlope(1).build()) + .build(); + assertEquals(BicycleOptimizeType.TRIANGLE, trianglePreferences.optimizeType()); + + var conflictingPreferences = BikePreferences + .of() + .withOptimizeType(BicycleOptimizeType.SAFE_STREETS) + .withForcedOptimizeTriangle(it -> it.withSlope(1).build()) + .build(); + assertEquals(BicycleOptimizeType.TRIANGLE, conflictingPreferences.optimizeType()); + + var emptyTrianglePreferences = BikePreferences + .of() + .withOptimizeType(BicycleOptimizeType.SAFE_STREETS) + .withForcedOptimizeTriangle(it -> it.build()) + .build(); + assertEquals(BicycleOptimizeType.SAFE_STREETS, emptyTrianglePreferences.optimizeType()); + } } diff --git a/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java b/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java index 300615269a1..d5b7733f3e8 100644 --- a/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java +++ b/src/test/java/org/opentripplanner/street/integration/BicycleRoutingTest.java @@ -75,7 +75,9 @@ private static String computePolyline(Graph graph, GenericLocation from, Generic request.setDateTime(dateTime); request.setFrom(from); request.setTo(to); - request.withPreferences(p -> p.withBike(it -> it.withOptimizeType(BicycleOptimizeType.QUICK))); + request.withPreferences(p -> + p.withBike(it -> it.withOptimizeType(BicycleOptimizeType.SHORTEST_DURATION)) + ); request.journey().direct().setMode(StreetMode.BIKE); var temporaryVertices = new TemporaryVerticesContainer( From a3f55d5d69c87669b1779b7dee2aa6abe56a7b31 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 9 Jan 2024 14:59:20 +0200 Subject: [PATCH 10/21] Update src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java Co-authored-by: Leonard Ehrenfried --- .../api/request/preference/VehicleWalkingPreferences.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java index 0abf2926f42..aa3631e1c6b 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleWalkingPreferences.java @@ -33,7 +33,7 @@ private VehicleWalkingPreferences() { } /** - * Sets the vehicle walking preferences and does some input value validation and rounds + * Sets the vehicle walking preferences, does some input value validation and rounds * reluctances and speed to not have too many decimals. */ private VehicleWalkingPreferences(Builder builder) { From 69bd96562f8f63a4aaec237292898709b15a62e1 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 9 Jan 2024 14:07:13 +0100 Subject: [PATCH 11/21] Add API mapper test for walk reluctance --- .../apis/gtfs/mapping/RouteRequestMapperTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java b/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java index f52b81717d4..b05dd77e2a9 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java +++ b/src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java @@ -2,6 +2,7 @@ import static graphql.execution.ExecutionContextBuilder.newExecutionContextBuilder; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.params.provider.Arguments.of; import static org.opentripplanner.routing.core.BicycleOptimizeType.SAFE_STREETS; @@ -195,6 +196,18 @@ void noTriangle(GraphQLTypes.GraphQLOptimizeType bot) { ); } + @Test + void walkReluctance() { + var reluctance = 119d; + Map arguments = Map.of("walkReluctance", reluctance); + + var routeRequest = RouteRequestMapper.toRouteRequest(executionContext(arguments), context); + assertEquals(reluctance, routeRequest.preferences().walk().reluctance()); + + var noParamsRequest = RouteRequestMapper.toRouteRequest(executionContext(Map.of()), context); + assertNotEquals(reluctance, noParamsRequest.preferences().walk().reluctance()); + } + private DataFetchingEnvironment executionContext(Map arguments) { ExecutionInput executionInput = ExecutionInput .newExecutionInput() From 9b075d2965c6c719f63900a95cc85a85f8a32e83 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 9 Jan 2024 17:48:42 +0200 Subject: [PATCH 12/21] Rename park cost/time --- docs/RouteRequest.md | 16 +++--- docs/RouterConfiguration.md | 8 +-- docs/examples/entur/router-config.json | 4 +- .../common/RequestToPreferencesMapper.java | 8 +-- .../model/DefaultRouteRequestType.java | 4 +- .../preference/VehicleParkingPreferences.java | 50 +++++++++---------- .../routerequest/VehicleParkingConfig.java | 12 ++--- .../street/model/edge/VehicleParkingEdge.java | 22 +++----- .../preference/BikePreferencesTest.java | 6 +-- .../preference/CarPreferencesTest.java | 6 +-- .../VehicleParkingPreferencesTest.java | 20 ++++---- .../street/integration/ParkAndRideTest.java | 8 +-- .../edge/StreetVehicleParkingLinkTest.java | 2 +- .../edge/VehicleParkingPreferredTagsTest.java | 2 +- .../standalone/config/router-config.json | 8 +-- 15 files changed, 83 insertions(+), 93 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index b95c58ec32f..06c7b55c521 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -57,8 +57,8 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    reluctance | `double` | A multiplier for how bad cycling is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | |    speed | `double` | Max bicycle speed along streets, in meters per second | *Optional* | `5.0` | 2.0 | |    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | -|       parkCost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | -|       parkTime | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       cost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | +|       time | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | |       [unpreferredVehicleParkingTagCost](#rd_bicycle_parking_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | |       [bannedVehicleParkingTags](#rd_bicycle_parking_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | |       [preferredVehicleParkingTags](#rd_bicycle_parking_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | @@ -92,8 +92,8 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |    reluctance | `double` | A multiplier for how bad driving is, compared to being in transit for equal lengths of time. | *Optional* | `2.0` | 2.0 | |    speed | `double` | Max car speed along streets, in meters per second | *Optional* | `40.0` | 2.0 | |    parking | `object` | Preferences for parking a vehicle. | *Optional* | | 2.5 | -|       parkCost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | -|       parkTime | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | +|       cost | `integer` | Cost to park a vehicle. | *Optional* | `120` | 2.0 | +|       time | `duration` | Time to park a vehicle. | *Optional* | `"PT1M"` | 2.0 | |       [unpreferredVehicleParkingTagCost](#rd_car_parking_unpreferredVehicleParkingTagCost) | `integer` | What cost to add if a parking facility doesn't contain a preferred tag. | *Optional* | `300` | 2.3 | |       [bannedVehicleParkingTags](#rd_car_parking_bannedVehicleParkingTags) | `string[]` | Tags with which a vehicle parking will not be used. If empty, no tags are banned. | *Optional* | | 2.1 | |       [preferredVehicleParkingTags](#rd_car_parking_preferredVehicleParkingTags) | `string[]` | Vehicle parking facilities that don't have one of these tags will receive an extra cost and will therefore be penalised. | *Optional* | | 2.3 | @@ -1071,8 +1071,8 @@ include stairs as a last result. "dropOffCost" : 30 }, "parking" : { - "parkTime" : "1m", - "parkCost" : 120 + "time" : "1m", + "cost" : 120 }, "triangle" : { "safety" : 0.4, @@ -1091,8 +1091,8 @@ include stairs as a last result. "dropOffCost" : 30 }, "parking" : { - "parkTime" : "5m", - "parkCost" : 600 + "time" : "5m", + "cost" : 600 } }, "walk" : { diff --git a/docs/RouterConfiguration.md b/docs/RouterConfiguration.md index f49a5bf9745..df08b852fd5 100644 --- a/docs/RouterConfiguration.md +++ b/docs/RouterConfiguration.md @@ -472,8 +472,8 @@ Used to group requests when monitoring OTP. "dropOffCost" : 30 }, "parking" : { - "parkTime" : "1m", - "parkCost" : 120 + "time" : "1m", + "cost" : 120 }, "triangle" : { "safety" : 0.4, @@ -492,8 +492,8 @@ Used to group requests when monitoring OTP. "dropOffCost" : 30 }, "parking" : { - "parkTime" : "5m", - "parkCost" : 600 + "time" : "5m", + "cost" : 600 } }, "walk" : { diff --git a/docs/examples/entur/router-config.json b/docs/examples/entur/router-config.json index cd8a393a3c3..ffdec9ded79 100644 --- a/docs/examples/entur/router-config.json +++ b/docs/examples/entur/router-config.json @@ -21,8 +21,8 @@ "dropOffCost": 30 }, "parking": { - "parkTime": "1m", - "parkCost": 120 + "time": "1m", + "cost": 120 } }, "car": { diff --git a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java index e4878e6c7d9..2a97cd63a75 100644 --- a/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java +++ b/src/main/java/org/opentripplanner/api/common/RequestToPreferencesMapper.java @@ -46,8 +46,8 @@ private void mapCar() { setIfNotNull(req.carReluctance, car::withReluctance); car.withParking(parking -> { mapParking(parking); - setIfNotNull(req.carParkCost, parking::withParkCost); - setIfNotNull(req.carParkTime, parking::withParkTime); + setIfNotNull(req.carParkCost, parking::withCost); + setIfNotNull(req.carParkTime, parking::withTime); }); car.withRental(this::mapRental); }); @@ -82,8 +82,8 @@ private void mapBike() { bike.withParking(parking -> { mapParking(parking); - setIfNotNull(req.bikeParkCost, parking::withParkCost); - setIfNotNull(req.bikeParkTime, parking::withParkTime); + setIfNotNull(req.bikeParkCost, parking::withCost); + setIfNotNull(req.bikeParkTime, parking::withTime); }); bike.withRental(this::mapRental); bike.withWalking(walk -> { diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java index aadd73dcddb..80b6418c314 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/DefaultRouteRequestType.java @@ -220,7 +220,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeParkTime") .description("Time to park a bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> (int) preferences.bike().parking().parkTime().toSeconds()) + .dataFetcher(env -> (int) preferences.bike().parking().time().toSeconds()) .build() ) .field( @@ -229,7 +229,7 @@ private GraphQLObjectType createGraphQLType() { .name("bikeParkCost") .description("Cost to park a bike.") .type(Scalars.GraphQLInt) - .dataFetcher(env -> preferences.bike().parking().parkCost().toSeconds()) + .dataFetcher(env -> preferences.bike().parking().cost().toSeconds()) .build() ) .field( diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java index c02862c4d79..f7183812c3a 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferences.java @@ -23,16 +23,16 @@ public final class VehicleParkingPreferences implements Serializable { private final Cost unpreferredVehicleParkingTagCost; private final VehicleParkingFilter filter; private final VehicleParkingFilter preferred; - private final Duration parkTime; - private final Cost parkCost; + private final Duration time; + private final Cost cost; /** Create a new instance with default values. */ private VehicleParkingPreferences() { this.unpreferredVehicleParkingTagCost = Cost.costOfMinutes(5); this.filter = VehicleParkingFilter.empty(); this.preferred = VehicleParkingFilter.empty(); - this.parkTime = Duration.ofMinutes(1); - this.parkCost = Cost.costOfMinutes(2); + this.time = Duration.ofMinutes(1); + this.cost = Cost.costOfMinutes(2); } private VehicleParkingPreferences(Builder builder) { @@ -47,8 +47,8 @@ private VehicleParkingPreferences(Builder builder) { builder.notPreferredVehicleParkingTags, builder.preferredVehicleParkingTags ); - this.parkTime = builder.parkTime; - this.parkCost = builder.parkCost; + this.time = builder.time; + this.cost = builder.cost; } public static VehicleParkingPreferences.Builder of() { @@ -85,13 +85,13 @@ public VehicleParkingFilter preferred() { } /** Time to park a vehicle */ - public Duration parkTime() { - return parkTime; + public Duration time() { + return time; } /** Cost of parking a bike. */ - public Cost parkCost() { - return parkCost; + public Cost cost() { + return cost; } @Override @@ -103,14 +103,14 @@ public boolean equals(Object o) { Objects.equals(unpreferredVehicleParkingTagCost, that.unpreferredVehicleParkingTagCost) && Objects.equals(filter, that.filter) && Objects.equals(preferred, that.preferred) && - Objects.equals(parkCost, that.parkCost) && - Objects.equals(parkTime, that.parkTime) + Objects.equals(cost, that.cost) && + Objects.equals(time, that.time) ); } @Override public int hashCode() { - return Objects.hash(unpreferredVehicleParkingTagCost, filter, preferred, parkCost, parkTime); + return Objects.hash(unpreferredVehicleParkingTagCost, filter, preferred, cost, time); } @Override @@ -124,8 +124,8 @@ public String toString() { ) .addObj("filter", filter, DEFAULT.filter) .addObj("preferred", preferred, DEFAULT.preferred) - .addObj("parkCost", parkCost, DEFAULT.parkCost) - .addObj("parkTime", parkTime, DEFAULT.parkTime) + .addObj("cost", cost, DEFAULT.cost) + .addObj("time", time, DEFAULT.time) .toString(); } @@ -137,8 +137,8 @@ public static class Builder { private List requiredVehicleParkingTags; private List preferredVehicleParkingTags; private List notPreferredVehicleParkingTags; - private Cost parkCost; - private Duration parkTime; + private Cost cost; + private Duration time; private Builder(VehicleParkingPreferences original) { this.original = original; @@ -147,8 +147,8 @@ private Builder(VehicleParkingPreferences original) { this.requiredVehicleParkingTags = original.filter.select(); this.preferredVehicleParkingTags = original.preferred.select(); this.notPreferredVehicleParkingTags = original.preferred.not(); - this.parkCost = original.parkCost; - this.parkTime = original.parkTime; + this.cost = original.cost; + this.time = original.time; } public Builder withUnpreferredVehicleParkingTagCost(int cost) { @@ -180,18 +180,18 @@ public Builder withNotPreferredVehicleParkingTags(Set notPreferredVehicl return this; } - public Builder withParkCost(int cost) { - this.parkCost = Cost.costOfSeconds(cost); + public Builder withCost(int cost) { + this.cost = Cost.costOfSeconds(cost); return this; } - public Builder withParkTime(int seconds) { - this.parkTime = Duration.ofSeconds(seconds); + public Builder withTime(int seconds) { + this.time = Duration.ofSeconds(seconds); return this; } - public Builder withParkTime(Duration duration) { - this.parkTime = duration; + public Builder withTime(Duration duration) { + this.time = duration; return this; } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java index 951129bc7b7..b4afc67e31c 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java @@ -52,19 +52,19 @@ Vehicle parking tags can originate from different places depending on the origin ) .asStringSet(List.of()) ) - .withParkTime( + .withTime( c - .of("parkTime") + .of("time") .since(V2_0) .summary("Time to park a vehicle.") - .asDuration(VehicleParkingPreferences.DEFAULT.parkTime()) + .asDuration(VehicleParkingPreferences.DEFAULT.time()) ) - .withParkCost( + .withCost( c - .of("parkCost") + .of("cost") .since(V2_0) .summary("Cost to park a vehicle.") - .asInt(VehicleParkingPreferences.DEFAULT.parkCost().toSeconds()) + .asInt(VehicleParkingPreferences.DEFAULT.cost().toSeconds()) ) .withPreferredVehicleParkingTags( c diff --git a/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java b/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java index be909c1dc4c..d32f13d6ea4 100644 --- a/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java +++ b/src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java @@ -94,20 +94,10 @@ protected State[] traverseUnPark(State s0) { if (streetMode.includesBiking()) { final BikePreferences bike = s0.getPreferences().bike(); - return traverseUnPark( - s0, - bike.parking().parkCost(), - bike.parking().parkTime(), - TraverseMode.BICYCLE - ); + return traverseUnPark(s0, bike.parking().cost(), bike.parking().time(), TraverseMode.BICYCLE); } else if (streetMode.includesDriving()) { final CarPreferences car = s0.getPreferences().car(); - return traverseUnPark( - s0, - car.parking().parkCost(), - car.parking().parkTime(), - TraverseMode.CAR - ); + return traverseUnPark(s0, car.parking().cost(), car.parking().time(), TraverseMode.CAR); } else { return State.empty(); } @@ -151,14 +141,14 @@ private State[] traversePark(State s0) { return traversePark( s0, - preferences.bike().parking().parkCost(), - preferences.bike().parking().parkTime() + preferences.bike().parking().cost(), + preferences.bike().parking().time() ); } else if (streetMode.includesDriving()) { return traversePark( s0, - preferences.car().parking().parkCost(), - preferences.car().parking().parkTime() + preferences.car().parking().cost(), + preferences.car().parking().time() ); } else { return State.empty(); diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java index a314aa48799..8a6ac3f4f45 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/BikePreferencesTest.java @@ -27,7 +27,7 @@ class BikePreferencesTest { .withBoardCost(BOARD_COST) .withOptimizeType(OPTIMIZE_TYPE) .withRental(rental -> rental.withPickupTime(RENTAL_PICKUP_TIME).build()) - .withParking(parking -> parking.withParkCost(PARK_COST).build()) + .withParking(parking -> parking.withCost(PARK_COST).build()) .withOptimizeTriangle(it -> it.withSlope(1).build()) .build(); @@ -64,7 +64,7 @@ void rental() { @Test void parking() { - var vehicleParking = VehicleParkingPreferences.of().withParkCost(PARK_COST).build(); + var vehicleParking = VehicleParkingPreferences.of().withCost(PARK_COST).build(); assertEquals(vehicleParking, subject.parking()); } @@ -91,7 +91,7 @@ void testToString() { "speed: 2.0, " + "reluctance: 1.2, " + "boardCost: $660, " + - "parking: VehicleParkingPreferences{parkCost: $30}, " + + "parking: VehicleParkingPreferences{cost: $30}, " + "rental: VehicleRentalPreferences{pickupTime: 30s}, " + "optimizeType: TRIANGLE, " + "optimizeTriangle: TimeSlopeSafetyTriangle[time=0.0, slope=1.0, safety=0.0]" + diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java index 3c0a294d7e2..4359ed9b33d 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/CarPreferencesTest.java @@ -30,7 +30,7 @@ class CarPreferencesTest { .withAccelerationSpeed(ACCELERATION_SPEED) .withDecelerationSpeed(DECELERATION_SPEED) .withRental(rental -> rental.withPickupTime(RENTAL_PICKUP_TIME).build()) - .withParking(parking -> parking.withParkCost(PARK_COST).build()) + .withParking(parking -> parking.withCost(PARK_COST).build()) .build(); @Test @@ -71,7 +71,7 @@ void rental() { @Test void parking() { - var vehicleParking = VehicleParkingPreferences.of().withParkCost(PARK_COST).build(); + var vehicleParking = VehicleParkingPreferences.of().withCost(PARK_COST).build(); assertEquals(vehicleParking, subject.parking()); } @@ -94,7 +94,7 @@ void testToString() { "CarPreferences{" + "speed: 20.0, " + "reluctance: 5.1, " + - "parking: VehicleParkingPreferences{parkCost: $30}, " + + "parking: VehicleParkingPreferences{cost: $30}, " + "rental: VehicleRentalPreferences{pickupTime: 30s}, " + "pickupTime: PT10M, " + "pickupCost: $500, " + diff --git a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java index 35666b53f9f..ff43a7ddba6 100644 --- a/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java +++ b/src/test/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java @@ -38,20 +38,20 @@ void unpreferredCost() { } @Test - void parkCost() { - assertEquals(PARKING_COST, subject.parkCost()); + void cost() { + assertEquals(PARKING_COST, subject.cost()); } @Test - void parkTime() { - assertEquals(PARKING_TIME, subject.parkTime()); + void time() { + assertEquals(PARKING_TIME, subject.time()); } @Test void testCopyOfEqualsAndHashCode() { // Create a copy, make a change and set it back again to force creating a new object - var other = subject.copyOf().withParkCost(10).build(); - var same = other.copyOf().withParkCost(PARKING_COST.toSeconds()).build(); + var other = subject.copyOf().withCost(10).build(); + var same = other.copyOf().withCost(PARKING_COST.toSeconds()).build(); assertEqualsAndHashCode(subject, other, same); } @@ -63,8 +63,8 @@ void testToString() { "unpreferredVehicleParkingTagCost: $360, " + "filter: VehicleParkingFilter{not: [tags=[not]], select: [tags=[bar]]}, " + "preferred: VehicleParkingFilter{not: [tags=[bar]], select: [tags=[foo]]}, " + - "parkCost: $240, " + - "parkTime: PT2M}", + "cost: $240, " + + "time: PT2M}", subject.toString() ); } @@ -81,8 +81,8 @@ private VehicleParkingPreferences createPreferences() { .withUnpreferredVehicleParkingTagCost(UNPREFERRED_COST) .withRequiredVehicleParkingTags(REQUIRED_TAGS) .withBannedVehicleParkingTags(BANNED_TAGS) - .withParkCost(PARKING_COST.toSeconds()) - .withParkTime(PARKING_TIME) + .withCost(PARKING_COST.toSeconds()) + .withTime(PARKING_TIME) .build(); } } diff --git a/src/test/java/org/opentripplanner/street/integration/ParkAndRideTest.java b/src/test/java/org/opentripplanner/street/integration/ParkAndRideTest.java index 6dd53ae0c6e..c4f7f52f4ec 100644 --- a/src/test/java/org/opentripplanner/street/integration/ParkAndRideTest.java +++ b/src/test/java/org/opentripplanner/street/integration/ParkAndRideTest.java @@ -142,16 +142,16 @@ protected List runStreetSearchAndCreateDescriptor( b.withParking(parking -> { parking.withRequiredVehicleParkingTags(requiredTags); parking.withBannedVehicleParkingTags(bannedTags); - parking.withParkCost(120); - parking.withParkTime(60); + parking.withCost(120); + parking.withTime(60); }) ) .withCar(c -> c.withParking(parking -> { parking.withRequiredVehicleParkingTags(requiredTags); parking.withBannedVehicleParkingTags(bannedTags); - parking.withParkCost(240); - parking.withParkTime(180); + parking.withCost(240); + parking.withTime(180); }) ) ); diff --git a/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java b/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java index a9932381b40..a2a052d3b5c 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLinkTest.java @@ -64,7 +64,7 @@ void foo(Set parkingTags, Set not, Set select, boolean s bike.withParking(parkingPreferences -> { parkingPreferences.withRequiredVehicleParkingTags(select); parkingPreferences.withBannedVehicleParkingTags(not); - parkingPreferences.withParkCost(0); + parkingPreferences.withCost(0); }); }) ); diff --git a/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java b/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java index 41ecbe162bb..5969121b6d6 100644 --- a/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java +++ b/src/test/java/org/opentripplanner/street/model/edge/VehicleParkingPreferredTagsTest.java @@ -88,7 +88,7 @@ private void runTest( bike.withParking(parkingPreferences -> { parkingPreferences.withUnpreferredVehicleParkingTagCost(EXTRA_COST); parkingPreferences.withPreferredVehicleParkingTags(preferredTags); - parkingPreferences.withParkCost(0); + parkingPreferences.withCost(0); }); }) ); diff --git a/src/test/resources/standalone/config/router-config.json b/src/test/resources/standalone/config/router-config.json index 9f6b336fde5..089c2481dca 100644 --- a/src/test/resources/standalone/config/router-config.json +++ b/src/test/resources/standalone/config/router-config.json @@ -33,8 +33,8 @@ "dropOffCost": 30 }, "parking": { - "parkTime": "1m", - "parkCost": 120 + "time": "1m", + "cost": 120 }, "triangle": { "safety": 0.4, @@ -53,8 +53,8 @@ "dropOffCost": 30 }, "parking": { - "parkTime": "5m", - "parkCost": 600 + "time": "5m", + "cost": 600 } }, "walk": { From 173df94640a2fa09351cdaa82568bb7f933041da Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Tue, 9 Jan 2024 17:59:47 +0200 Subject: [PATCH 13/21] Update docs --- docs/RouteRequest.md | 6 +++--- .../standalone/config/routerequest/RouteRequestConfig.java | 2 +- .../config/routerequest/VehicleWalkingConfig.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/RouteRequest.md b/docs/RouteRequest.md index 06c7b55c521..f9a4e7e5d2f 100644 --- a/docs/RouteRequest.md +++ b/docs/RouteRequest.md @@ -79,7 +79,7 @@ and in the [transferRequests in build-config.json](BuildConfiguration.md#transfe |       time | `double` | Relative importance of duration of travel (range 0-1). | *Optional* | `0.0` | 2.0 | |    walk | `object` | Preferences for walking a vehicle. | *Optional* | | 2.5 | |       [hopCost](#rd_bicycle_walk_hopCost) | `integer` | The cost of hopping on or off a vehicle. | *Optional* | `0` | 2.0 | -|       [hopTime](#rd_bicycle_walk_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle in seconds. | *Optional* | `"PT0S"` | 2.0 | +|       [hopTime](#rd_bicycle_walk_hopTime) | `duration` | The time it takes the user to hop on or off a vehicle. | *Optional* | `"PT0S"` | 2.0 | |       reluctance | `double` | A multiplier for how bad walking with a vehicle is, compared to being in transit for equal lengths of time. | *Optional* | `5.0` | 2.1 | |       speed | `double` | The user's vehicle walking speed in meters/second. Defaults to approximately 3 MPH. | *Optional* | `1.33` | 2.1 | |       stairsReluctance | `double` | How bad is it to walk the vehicle up/down a flight of stairs compared to taking a detour. | *Optional* | `10.0` | 2.3 | @@ -440,7 +440,7 @@ Sometimes there is a need to configure a longer alighting times for specific mod Prevents unnecessary transfers by adding a cost for boarding a transit vehicle. -This is the cost that is used when boarding while cycling.This is usually higher that walkBoardCost. +This is the cost that is used when boarding while cycling. This is usually higher that walkBoardCost.

optimization

@@ -541,7 +541,7 @@ not meant for controlling the cost of those events. **Since version:** `2.0` ∙ **Type:** `duration` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"PT0S"` **Path:** /routingDefaults/bicycle/walk -The time it takes the user to hop on or off a vehicle in seconds. +The time it takes the user to hop on or off a vehicle. Time it takes to rent or park a vehicle have their own parameters and this is not meant for controlling the duration of those events. diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 8aaa0b1d243..6ee164f0083 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -362,7 +362,7 @@ private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder bu "Prevents unnecessary transfers by adding a cost for boarding a transit vehicle." ) .description( - "This is the cost that is used when boarding while cycling." + + "This is the cost that is used when boarding while cycling. " + "This is usually higher that walkBoardCost." ) .asInt(dft.boardCost()) diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java index ac6ac7d92f4..6bc3bd3ffca 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java @@ -38,7 +38,7 @@ private static void mapVehicleWalkingPreferences( c .of("hopTime") .since(V2_0) - .summary("The time it takes the user to hop on or off a vehicle in seconds.") + .summary("The time it takes the user to hop on or off a vehicle.") .description( """ Time it takes to rent or park a vehicle have their own parameters and this is not meant From f290e95b5f38973c5e8a7d4079ca698e59dfc78d Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Wed, 17 Jan 2024 17:24:46 +0200 Subject: [PATCH 14/21] Move public methods up --- .../TriangleOptimizationConfig.java | 20 +++++++++---------- .../routerequest/VehicleParkingConfig.java | 18 ++++++++--------- .../routerequest/VehicleRentalConfig.java | 15 ++++++++------ .../routerequest/VehicleWalkingConfig.java | 18 ++++++++--------- 4 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java index 361e591891c..e6da735a4ac 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/TriangleOptimizationConfig.java @@ -8,6 +8,16 @@ public class TriangleOptimizationConfig { + static void mapOptimizationTriangle(NodeAdapter c, TimeSlopeSafetyTriangle.Builder preferences) { + var optimizationTriangle = c + .of("triangle") + .since(V2_5) + .summary("Triangle optimization criteria.") + .description("Optimization type doesn't need to be defined if these values are defined.") + .asObject(); + mapTriangleParameters(optimizationTriangle, preferences); + } + private static void mapTriangleParameters( NodeAdapter c, TimeSlopeSafetyTriangle.Builder builder @@ -41,14 +51,4 @@ private static void mapTriangleParameters( .asDouble(builder.safety()) ); } - - static void mapOptimizationTriangle(NodeAdapter c, TimeSlopeSafetyTriangle.Builder preferences) { - var optimizationTriangle = c - .of("triangle") - .since(V2_5) - .summary("Triangle optimization criteria.") - .description("Optimization type doesn't need to be defined if these values are defined.") - .asObject(); - mapTriangleParameters(optimizationTriangle, preferences); - } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java index b4afc67e31c..218ac3b33df 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleParkingConfig.java @@ -11,6 +11,15 @@ public class VehicleParkingConfig { + static void mapParking(NodeAdapter c, VehicleParkingPreferences.Builder preferences) { + var vehicleParking = c + .of("parking") + .since(V2_5) + .summary("Preferences for parking a vehicle.") + .asObject(); + mapParkingPreferences(vehicleParking, preferences); + } + private static void mapParkingPreferences( NodeAdapter c, VehicleParkingPreferences.Builder builder @@ -81,13 +90,4 @@ Vehicle parking tags can originate from different places depending on the origin .asStringSet(List.of()) ); } - - static void mapParking(NodeAdapter c, VehicleParkingPreferences.Builder preferences) { - var vehicleParking = c - .of("parking") - .since(V2_5) - .summary("Preferences for parking a vehicle.") - .asObject(); - mapParkingPreferences(vehicleParking, preferences); - } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java index f862e9b9628..401d977762d 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleRentalConfig.java @@ -10,7 +10,15 @@ public class VehicleRentalConfig { - static void mapRentalPreferences(NodeAdapter c, VehicleRentalPreferences.Builder builder) { + static void mapRental(NodeAdapter c, VehicleRentalPreferences.Builder preferences) { + var vehicleRental = c.of("rental").since(V2_3).summary("Vehicle rental options").asObject(); + mapRentalPreferences(vehicleRental, preferences); + } + + private static void mapRentalPreferences( + NodeAdapter c, + VehicleRentalPreferences.Builder builder + ) { var dft = builder.original(); builder .withDropOffCost( @@ -87,9 +95,4 @@ static void mapRentalPreferences(NodeAdapter c, VehicleRentalPreferences.Builder .asStringSet(dft.bannedNetworks()) ); } - - static void mapRental(NodeAdapter c, VehicleRentalPreferences.Builder preferences) { - var vehicleRental = c.of("rental").since(V2_3).summary("Vehicle rental options").asObject(); - mapRentalPreferences(vehicleRental, preferences); - } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java index 6bc3bd3ffca..f2ba922c8e3 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/VehicleWalkingConfig.java @@ -10,6 +10,15 @@ public class VehicleWalkingConfig { + static void mapVehicleWalking(NodeAdapter c, VehicleWalkingPreferences.Builder preferences) { + var vehicleWalking = c + .of("walk") + .since(V2_5) + .summary("Preferences for walking a vehicle.") + .asObject(); + mapVehicleWalkingPreferences(vehicleWalking, preferences); + } + private static void mapVehicleWalkingPreferences( NodeAdapter c, VehicleWalkingPreferences.Builder builder @@ -70,13 +79,4 @@ private static void mapVehicleWalkingPreferences( .asDouble(dft.stairsReluctance()) ); } - - static void mapVehicleWalking(NodeAdapter c, VehicleWalkingPreferences.Builder preferences) { - var vehicleWalking = c - .of("walk") - .since(V2_5) - .summary("Preferences for walking a vehicle.") - .asObject(); - mapVehicleWalkingPreferences(vehicleWalking, preferences); - } } From f11a81ad6be01ea25ac72156f1d4064e48f1f116 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Wed, 17 Jan 2024 17:37:57 +0200 Subject: [PATCH 15/21] Rename variables --- .../routerequest/RouteRequestConfig.java | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java index 6ee164f0083..ed3fa29cc8e 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerequest/RouteRequestConfig.java @@ -334,19 +334,19 @@ The board time is added to the time when going from the stop (offboard) to onboa ); } - private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder builder) { + private static void mapBikePreferences(NodeAdapter root, BikePreferences.Builder builder) { var dft = builder.original(); - NodeAdapter cb = c.of("bicycle").since(V2_5).summary("Bicycle preferences.").asObject(); + NodeAdapter c = root.of("bicycle").since(V2_5).summary("Bicycle preferences.").asObject(); builder .withSpeed( - cb + c .of("speed") .since(V2_0) .summary("Max bicycle speed along streets, in meters per second") .asDouble(dft.speed()) ) .withReluctance( - cb + c .of("reluctance") .since(V2_0) .summary( @@ -355,7 +355,7 @@ private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder bu .asDouble(dft.reluctance()) ) .withBoardCost( - cb + c .of("boardCost") .since(V2_0) .summary( @@ -368,7 +368,7 @@ private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder bu .asInt(dft.boardCost()) ) .withOptimizeType( - cb + c .of("optimization") .since(V2_0) .summary("The set of characteristics that the user wants to optimize for.") @@ -378,10 +378,10 @@ private static void mapBikePreferences(NodeAdapter c, BikePreferences.Builder bu .asEnum(dft.optimizeType()) ) // triangle overrides the optimization type if defined - .withForcedOptimizeTriangle(it -> mapOptimizationTriangle(cb, it)) - .withWalking(it -> mapVehicleWalking(cb, it)) - .withParking(it -> mapParking(cb, it)) - .withRental(it -> mapRental(cb, it)); + .withForcedOptimizeTriangle(it -> mapOptimizationTriangle(c, it)) + .withWalking(it -> mapVehicleWalking(c, it)) + .withParking(it -> mapParking(c, it)) + .withRental(it -> mapRental(c, it)); } private static void mapStreetPreferences(NodeAdapter c, StreetPreferences.Builder builder) { @@ -570,19 +570,19 @@ The street search(AStar) aborts after this duration and any paths found are retu ); } - private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder builder) { + private static void mapCarPreferences(NodeAdapter root, CarPreferences.Builder builder) { var dft = builder.original(); - NodeAdapter cc = c.of("car").since(V2_5).summary("Car preferences.").asObject(); + NodeAdapter c = root.of("car").since(V2_5).summary("Car preferences.").asObject(); builder .withSpeed( - cc + c .of("speed") .since(V2_0) .summary("Max car speed along streets, in meters per second") .asDouble(dft.speed()) ) .withReluctance( - cc + c .of("reluctance") .since(V2_0) .summary( @@ -591,35 +591,35 @@ private static void mapCarPreferences(NodeAdapter c, CarPreferences.Builder buil .asDouble(dft.reluctance()) ) .withPickupCost( - cc + c .of("pickupCost") .since(V2_1) .summary("Add a cost for car pickup changes when a pickup or drop off takes place") .asInt(dft.pickupCost().toSeconds()) ) .withPickupTime( - cc + c .of("pickupTime") .since(V2_1) .summary("Add a time for car pickup changes when a pickup or drop off takes place") .asDuration(dft.pickupTime()) ) .withAccelerationSpeed( - cc + c .of("accelerationSpeed") .since(V2_0) .summary("The acceleration speed of an automobile, in meters per second per second.") .asDouble(dft.accelerationSpeed()) ) .withDecelerationSpeed( - cc + c .of("decelerationSpeed") .since(V2_0) .summary("The deceleration speed of an automobile, in meters per second per second.") .asDouble(dft.decelerationSpeed()) ) - .withParking(it -> mapParking(cc, it)) - .withRental(it -> mapRental(cc, it)); + .withParking(it -> mapParking(c, it)) + .withRental(it -> mapRental(c, it)); } private static void mapSystemPreferences(NodeAdapter c, SystemPreferences.Builder builder) { @@ -670,19 +670,19 @@ private static void mapSystemPreferences(NodeAdapter c, SystemPreferences.Builde } } - private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder walk) { + private static void mapWalkPreferences(NodeAdapter root, WalkPreferences.Builder walk) { var dft = walk.original(); - NodeAdapter cw = c.of("walk").since(V2_5).summary("Walking preferences.").asObject(); + NodeAdapter c = root.of("walk").since(V2_5).summary("Walking preferences.").asObject(); walk .withSpeed( - cw + c .of("speed") .since(V2_0) .summary("The user's walking speed in meters/second.") .asDouble(dft.speed()) ) .withReluctance( - cw + c .of("reluctance") .since(V2_0) .summary( @@ -700,7 +700,7 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asDouble(dft.reluctance()) ) .withBoardCost( - cw + c .of("boardCost") .since(V2_0) .summary( @@ -712,14 +712,14 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asInt(dft.boardCost()) ) .withStairsReluctance( - cw + c .of("stairsReluctance") .since(V2_0) .summary("Used instead of walkReluctance for stairs.") .asDouble(dft.stairsReluctance()) ) .withStairsTimeFactor( - cw + c .of("stairsTimeFactor") .since(V2_1) .summary( @@ -734,7 +734,7 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asDouble(dft.stairsTimeFactor()) ) .withSafetyFactor( - cw + c .of("safetyFactor") .since(V2_2) .summary("Factor for how much the walk safety is considered in routing.") @@ -744,7 +744,7 @@ private static void mapWalkPreferences(NodeAdapter c, WalkPreferences.Builder wa .asDouble(dft.safetyFactor()) ) .withEscalatorReluctance( - cw + c .of("escalatorReluctance") .since(V2_4) .summary( From ac45106c7956d15ca7b5cb0621664ca48f7c8b42 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 18 Jan 2024 08:59:17 +0100 Subject: [PATCH 16/21] Revert REST API spelling of real-time --- .../ext/restapi/mapping/TripTimeMapper.java | 8 ++++---- .../ext/restapi/model/ApiTripTimeShort.java | 8 ++++---- .../ext/restapi/model/ApiVehicleParkingWithEntrance.java | 4 ++-- .../algorithm/mapping/__snapshots__/CarSnapshotTest.snap | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java index f1f37e6d8b4..46607cccb6a 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/TripTimeMapper.java @@ -29,13 +29,13 @@ public static ApiTripTimeShort mapToApi(TripTimeOnDate domain) { api.stopCount = domain.getStopCount(); api.scheduledArrival = domain.getScheduledArrival(); api.scheduledDeparture = domain.getScheduledDeparture(); - api.realTimeArrival = domain.getRealtimeArrival(); - api.realTimeDeparture = domain.getRealtimeDeparture(); + api.realimeArrival = domain.getRealtimeArrival(); + api.realtimeDeparture = domain.getRealtimeDeparture(); api.arrivalDelay = domain.getArrivalDelay(); api.departureDelay = domain.getDepartureDelay(); api.timepoint = domain.isTimepoint(); - api.realTime = domain.isRealtime(); - api.realTimeState = ApiRealTimeState.RealTimeState(domain.getRealTimeState()); + api.realtime = domain.isRealtime(); + api.realtimeState = ApiRealTimeState.RealTimeState(domain.getRealTimeState()); api.blockId = domain.getBlockId(); api.headsign = I18NStringMapper.mapToApi(domain.getHeadsign(), null); api.tripId = FeedScopedIdMapper.mapToApi(domain.getTrip().getId()); diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java index 21c6010c5a2..c0337ba18d4 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiTripTimeShort.java @@ -11,13 +11,13 @@ public class ApiTripTimeShort implements Serializable { public int stopCount; public int scheduledArrival = UNDEFINED; public int scheduledDeparture = UNDEFINED; - public int realTimeArrival = UNDEFINED; - public int realTimeDeparture = UNDEFINED; + public int realimeArrival = UNDEFINED; + public int realtimeDeparture = UNDEFINED; public int arrivalDelay = UNDEFINED; public int departureDelay = UNDEFINED; public boolean timepoint = false; - public boolean realTime = false; - public ApiRealTimeState realTimeState = ApiRealTimeState.SCHEDULED; + public boolean realtime = false; + public ApiRealTimeState realtimeState = ApiRealTimeState.SCHEDULED; public long serviceDay; public String tripId; public String blockId; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java index 68a9f37dfe4..79c5decbaeb 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/model/ApiVehicleParkingWithEntrance.java @@ -81,7 +81,7 @@ public class ApiVehicleParkingWithEntrance { /** * True if real-time information is used for checking availability. */ - public final boolean realTime; + public final boolean realtime; ApiVehicleParkingWithEntrance( String id, @@ -114,7 +114,7 @@ public class ApiVehicleParkingWithEntrance { this.hasWheelchairAccessibleCarPlaces = hasWheelchairAccessibleCarPlaces; this.capacity = capacity; this.availability = availability; - this.realTime = realTime; + this.realtime = realTime; } public static ApiVehicleParkingWithEntranceBuilder builder() { diff --git a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap index 31d59483807..8f527b15bf7 100644 --- a/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap +++ b/src/test/java/org/opentripplanner/routing/algorithm/mapping/__snapshots__/CarSnapshotTest.snap @@ -106,7 +106,7 @@ org.opentripplanner.routing.algorithm.mapping.CarSnapshotTest.directCarPark=[ "hasWheelchairAccessibleCarPlaces" : false, "id" : "OSM:OSMWay/-102488", "name" : "P+R", - "realTime" : false, + "realtime" : false, "tags" : [ "osm:amenity=parking" ] @@ -137,7 +137,7 @@ org.opentripplanner.routing.algorithm.mapping.CarSnapshotTest.directCarPark=[ "hasWheelchairAccessibleCarPlaces" : false, "id" : "OSM:OSMWay/-102488", "name" : "P+R", - "realTime" : false, + "realtime" : false, "tags" : [ "osm:amenity=parking" ] From aaff0ecb45aa8efe5efd09f43ed1ec945806b446 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Thu, 18 Jan 2024 11:51:39 +0200 Subject: [PATCH 17/21] Make builder field private --- .../routing/api/request/preference/BikePreferences.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java index 2d887eba596..26da1476b38 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java +++ b/src/main/java/org/opentripplanner/routing/api/request/preference/BikePreferences.java @@ -166,8 +166,7 @@ public static class Builder { private VehicleRentalPreferences rental; private BicycleOptimizeType optimizeType; private TimeSlopeSafetyTriangle optimizeTriangle; - - public VehicleWalkingPreferences walking; + private VehicleWalkingPreferences walking; public Builder(BikePreferences original) { this.original = original; From ed51e526f1c026503cd9ea5d2b861304d9b43ed6 Mon Sep 17 00:00:00 2001 From: Joel Lappalainen Date: Thu, 18 Jan 2024 15:56:10 +0200 Subject: [PATCH 18/21] Move class to correct package --- .../ext/restapi/mapping}/LegacyBicycleOptimizeType.java | 2 +- .../ext/restapi/resources/RequestToPreferencesMapper.java | 2 +- .../opentripplanner/ext/restapi/resources/RoutingResource.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/{main/java/org/opentripplanner/framework/i18n => ext/java/org/opentripplanner/ext/restapi/mapping}/LegacyBicycleOptimizeType.java (93%) diff --git a/src/main/java/org/opentripplanner/framework/i18n/LegacyBicycleOptimizeType.java b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyBicycleOptimizeType.java similarity index 93% rename from src/main/java/org/opentripplanner/framework/i18n/LegacyBicycleOptimizeType.java rename to src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyBicycleOptimizeType.java index 1cc262ad720..ff50a03534b 100644 --- a/src/main/java/org/opentripplanner/framework/i18n/LegacyBicycleOptimizeType.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/mapping/LegacyBicycleOptimizeType.java @@ -1,4 +1,4 @@ -package org.opentripplanner.api.mapping; +package org.opentripplanner.ext.restapi.mapping; import org.opentripplanner.routing.core.BicycleOptimizeType; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java index d8ebeb30f63..2236e7fbcaa 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RequestToPreferencesMapper.java @@ -2,7 +2,7 @@ import jakarta.validation.constraints.NotNull; import java.util.function.Consumer; -import org.opentripplanner.api.mapping.LegacyBicycleOptimizeType; +import org.opentripplanner.ext.restapi.mapping.LegacyBicycleOptimizeType; import org.opentripplanner.framework.lang.ObjectUtils; import org.opentripplanner.routing.algorithm.filterchain.api.TransitGeneralizedCostFilterParams; import org.opentripplanner.routing.api.request.framework.CostLinearFunction; diff --git a/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java index 49659cfe940..0cd16217ca7 100644 --- a/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java +++ b/src/ext/java/org/opentripplanner/ext/restapi/resources/RoutingResource.java @@ -18,9 +18,9 @@ import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; -import org.opentripplanner.api.mapping.LegacyBicycleOptimizeType; import org.opentripplanner.api.parameter.QualifiedModeSet; import org.opentripplanner.ext.dataoverlay.api.DataOverlayParameters; +import org.opentripplanner.ext.restapi.mapping.LegacyBicycleOptimizeType; import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.lang.StringUtils; import org.opentripplanner.framework.time.DurationUtils; From dcd0a5e4ae927a7b8e8c2a1513e3660d96ad8393 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 18 Jan 2024 20:52:15 +0000 Subject: [PATCH 19/21] Add changelog entry for #5582 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 4af1393c748..97561c64ec2 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -76,6 +76,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Add stop layer to new Debug UI [#5602](https://github.com/opentripplanner/OpenTripPlanner/pull/5602) - Use fallback timezone if no transit data is loaded [#4652](https://github.com/opentripplanner/OpenTripPlanner/pull/4652) - Add new path for GTFS GraphQL API, remove batch feature [#5581](https://github.com/opentripplanner/OpenTripPlanner/pull/5581) +- Restructure walk/bicycle/car preferences in router-config.json [#5582](https://github.com/opentripplanner/OpenTripPlanner/pull/5582) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13) From 1832b6740b3c507144d3f928650647db5f5710bd Mon Sep 17 00:00:00 2001 From: OTP Serialization Version Bot Date: Thu, 18 Jan 2024 20:52:38 +0000 Subject: [PATCH 20/21] Bump serialization version id for #5582 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c3f7392bb42..34b5a9c7d79 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ - 136 + 137 30.1 2.50 From 86cffd6d492c61f42dba31f3ec9b91a1be0ee412 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Thu, 18 Jan 2024 20:53:22 +0000 Subject: [PATCH 21/21] Add changelog entry for #5629 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 97561c64ec2..6f27f60d947 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -77,6 +77,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Use fallback timezone if no transit data is loaded [#4652](https://github.com/opentripplanner/OpenTripPlanner/pull/4652) - Add new path for GTFS GraphQL API, remove batch feature [#5581](https://github.com/opentripplanner/OpenTripPlanner/pull/5581) - Restructure walk/bicycle/car preferences in router-config.json [#5582](https://github.com/opentripplanner/OpenTripPlanner/pull/5582) +- Revert REST API spelling change of real-time [#5629](https://github.com/opentripplanner/OpenTripPlanner/pull/5629) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.4.0 (2023-09-13)