diff --git a/src/main/java/org/opentripplanner/model/plan/Itinerary.java b/src/main/java/org/opentripplanner/model/plan/Itinerary.java index 69365a4dd66..ac98bcd8000 100644 --- a/src/main/java/org/opentripplanner/model/plan/Itinerary.java +++ b/src/main/java/org/opentripplanner/model/plan/Itinerary.java @@ -164,6 +164,13 @@ public boolean isOnStreetAllTheWay() { return isStreetOnly(); } + /** + * Returns true if this itinerary has only flex and walking legs. + */ + public boolean isFlexAndWalkOnly() { + return legs.stream().allMatch(l -> l.isFlexibleTrip() || l.isWalkingLeg()); + } + /** TRUE if at least one leg is a transit leg. */ public boolean hasTransit() { return legs diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java index 071814a7abf..7cffe128a99 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/ItineraryListFilterChainBuilder.java @@ -25,6 +25,7 @@ import org.opentripplanner.routing.algorithm.filterchain.filters.street.RemoveNonTransitItinerariesBasedOnGeneralizedCost; import org.opentripplanner.routing.algorithm.filterchain.filters.street.RemoveParkAndRideWithMostlyWalkingFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.street.RemoveWalkOnlyFilter; +import org.opentripplanner.routing.algorithm.filterchain.filters.system.FlexSearchWindowFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.system.NumItinerariesFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.system.OutsideSearchWindowFilter; import org.opentripplanner.routing.algorithm.filterchain.filters.system.PagingFilter; @@ -468,6 +469,7 @@ public ItineraryListFilterChain build() { filters, new OutsideSearchWindowFilter(earliestDepartureTime, searchWindow) ); + addRemoveFilter(filters, new FlexSearchWindowFilter(earliestDepartureTime)); } // Remove itineraries present in the page retrieved before this page/search. diff --git a/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/FlexSearchWindowFilter.java b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/FlexSearchWindowFilter.java new file mode 100644 index 00000000000..bfacc1a815c --- /dev/null +++ b/src/main/java/org/opentripplanner/routing/algorithm/filterchain/filters/system/FlexSearchWindowFilter.java @@ -0,0 +1,46 @@ +package org.opentripplanner.routing.algorithm.filterchain.filters.system; + +import java.time.Instant; +import java.util.function.Predicate; +import org.opentripplanner.model.plan.Itinerary; +import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger; + +/** + * The flex router doesn't use the transit router's time window but nevertheless using it + * for filtering is useful when combining flex with transit. + *
+ * The flex router also searches the previous day (arrive by) or the next one (depart after).
+ * If you didn't do it you could get yesterday's or tomorrow's results where you would not expect it.
+ */
+public class FlexSearchWindowFilter implements RemoveItineraryFlagger {
+
+ public static final String TAG = "outside-flex-window";
+
+ private final Instant earliestDepartureTime;
+
+ public FlexSearchWindowFilter(Instant earliestDepartureTime) {
+ this.earliestDepartureTime = earliestDepartureTime;
+ }
+
+ @Override
+ public String name() {
+ return TAG;
+ }
+
+ @Override
+ public Predicate
+ * In some cases the access is time-shifted after the end of the search-window. These results
* should appear again when paging to the next page. Hence, this filter will remove
* such itineraries. The same is true for when paging to the previous page for arriveBy=true.
*
diff --git a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java
index 142ced31504..21531fbf591 100644
--- a/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java
+++ b/src/test/java/org/opentripplanner/model/plan/ItineraryTest.java
@@ -258,6 +258,12 @@ void bothPenalties() {
);
}
+ @Test
+ void flexAndWalk() {
+ assertFalse(itinerary().isFlexAndWalkOnly());
+ assertTrue(newItinerary(A).flex(T11_10, T11_20, B).build().isFlexAndWalkOnly());
+ }
+
private static Itinerary itinerary() {
return newItinerary(A).bus(1, T11_04, T11_14, B).build();
}