Skip to content

Commit

Permalink
Filter flex resuls also by sort order
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardehrenfried committed Oct 10, 2024
1 parent 023c693 commit fca7ba9
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 8 deletions.
12 changes: 12 additions & 0 deletions src/main/java/org/opentripplanner/model/plan/SortOrder.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,16 @@ public enum SortOrder {
public boolean isSortedByAscendingArrivalTime() {
return this == STREET_AND_ARRIVAL_TIME;
}

/**
* The itineraries are sorted with by departure time with the latest departure time first. When
* paging we need to know which end of the list of itineraries we should crop. This method is used
* to decide that together with the current page type (next/previous).
* <p>
* This returns {@code false} for the default depart-after search, and {@code true} for an
* arrive-by search.
*/
public boolean isSortedByDescendingDepartureTime() {
return this == STREET_AND_DEPARTURE_TIME;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,10 @@ public ItineraryListFilterChain build() {
}

if (earliestDepartureTime != null && filterDirectFlexByEarliestDeparture) {
addRemoveFilter(filters, new FlexSearchWindowFilter(earliestDepartureTime));
addRemoveFilter(
filters,
new FlexSearchWindowFilter(earliestDepartureTime, searchWindow, sortOrder)
);
}

// Remove itineraries present in the page retrieved before this page/search.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.opentripplanner.routing.algorithm.filterchain.filters.system;

import java.time.Duration;
import java.time.Instant;
import java.util.function.Predicate;
import org.opentripplanner.model.plan.Itinerary;
import org.opentripplanner.model.plan.SortOrder;
import org.opentripplanner.routing.algorithm.filterchain.framework.spi.RemoveItineraryFlagger;

/**
Expand All @@ -18,9 +20,17 @@ public class FlexSearchWindowFilter implements RemoveItineraryFlagger {
public static final String TAG = "outside-flex-window";

private final Instant earliestDepartureTime;

public FlexSearchWindowFilter(Instant earliestDepartureTime) {
private final Instant latestArrivalTime;
private final SortOrder sortOrder;

public FlexSearchWindowFilter(
Instant earliestDepartureTime,
Duration searchWindow,
SortOrder sortOrder
) {
this.earliestDepartureTime = earliestDepartureTime;
this.latestArrivalTime = earliestDepartureTime.plus(searchWindow);
this.sortOrder = sortOrder;
}

@Override
Expand All @@ -31,9 +41,12 @@ public String name() {
@Override
public Predicate<Itinerary> shouldBeFlaggedForRemoval() {
return it -> {
if (it.isDirectFlex()) {
if (it.isDirectFlex() && sortOrder.isSortedByDescendingDepartureTime()) {
var time = it.startTime().toInstant();
return time.isBefore(earliestDepartureTime);
} else if (it.isDirectFlex() && sortOrder.isSortedByAscendingArrivalTime()) {
var time = it.startTime().toInstant();
return time.isAfter(latestArrivalTime);
} else {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package org.opentripplanner.routing.algorithm.filterchain.filters.system;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.opentripplanner.framework.time.TimeUtils.time;
import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary;

import java.time.Duration;
import java.time.Instant;
import java.util.List;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.opentripplanner.model.plan.PlanTestConstants;
import org.opentripplanner.model.plan.SortOrder;
import org.opentripplanner.model.plan.TestItineraryBuilder;

class FlexSearchWindowFilterTest implements PlanTestConstants {
Expand All @@ -19,9 +22,13 @@ class FlexSearchWindowFilterTest implements PlanTestConstants {

@ParameterizedTest
@ValueSource(strings = { "09:20", "09:21", "13:20" })
void keepFlexItinerariesAfterLDT(String startTime) {
void keepArriveByFlexItinerariesAfterEDT(String startTime) {
var edt = "9:20";
var subject = new FlexSearchWindowFilter(TestItineraryBuilder.newTime(time(edt)).toInstant());
var subject = new FlexSearchWindowFilter(
TestItineraryBuilder.newTime(time(edt)).toInstant(),
Duration.ofMinutes(30),
SortOrder.STREET_AND_DEPARTURE_TIME
);

var itin = newItinerary(A, time(startTime))
.flex(T11_00, T11_30, B)
Expand All @@ -33,8 +40,12 @@ void keepFlexItinerariesAfterLDT(String startTime) {

@ParameterizedTest
@ValueSource(strings = { "00:00", "00:01", "09:19" })
void removeFlexItinerariesBeforeLDT(String startTime) {
var subject = new FlexSearchWindowFilter(LATEST_DEPARTURE_TIME);
void removeArriveByFlexItinerariesBeforeEDT(String startTime) {
var subject = new FlexSearchWindowFilter(
LATEST_DEPARTURE_TIME,
Duration.ofMinutes(30),
SortOrder.STREET_AND_DEPARTURE_TIME
);

var itin = newItinerary(A, time(startTime))
.flex(T11_00, T11_30, B)
Expand All @@ -43,4 +54,21 @@ void removeFlexItinerariesBeforeLDT(String startTime) {

assertThat(subject.flagForRemoval(List.of(itin))).isEmpty();
}

@ParameterizedTest
@ValueSource(strings = { "12:00" })
void removeDepartAtFlexItinerariesAfterLAT(String startTime) {
var subject = new FlexSearchWindowFilter(
LATEST_DEPARTURE_TIME,
Duration.ofMinutes(30),
SortOrder.STREET_AND_ARRIVAL_TIME
);

var itin = newItinerary(A, time(startTime))
.flex(T11_00, T11_30, B)
.withIsSearchWindowAware(false)
.build();

assertEquals(subject.flagForRemoval(List.of(itin)), List.of(itin));
}
}

0 comments on commit fca7ba9

Please sign in to comment.