Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue with cancellations on trip patterns that run after midnight #5719

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public class TransitLayer {
/**
* Transit data required for routing, indexed by each local date(Graph TimeZone) it runs through.
* A Trip "runs through" a date if any of its arrivals or departures is happening on that date.
* The same trip pattern can therefore have multiple running dates and trip pattern is not
* required to "run" on its service date.
*/
private final HashMap<LocalDate, List<TripPatternForDate>> tripPatternsRunningOnDate;

Expand Down Expand Up @@ -94,7 +96,12 @@ public StopLocation getStopByIndex(int stop) {
return stop == -1 ? null : this.stopModel.stopByIndex(stop);
}

public Collection<TripPatternForDate> getTripPatternsForDate(LocalDate date) {
/**
* Returns trip patterns for the given running date. Running date is not necessarily the same
* as the service date. A Trip "runs through" a date if any of its arrivals or departures is
* happening on that date. Trip pattern can have multiple running dates.
*/
public Collection<TripPatternForDate> getTripPatternsForRunningDate(LocalDate date) {
return tripPatternsRunningOnDate.getOrDefault(date, List.of());
}

Expand All @@ -112,16 +119,29 @@ public int getStopCount() {
return stopModel.stopIndexSize();
}

/**
* Returns a copy of the list of trip patterns for the given running date. Running date is not
* necessarily the same as the service date. A Trip "runs through" a date if any of its arrivals
* or departures is happening on that date. Trip pattern can have multiple running dates.
*/
public List<TripPatternForDate> getTripPatternsRunningOnDateCopy(LocalDate runningPeriodDate) {
List<TripPatternForDate> tripPatternForDate = tripPatternsRunningOnDate.get(runningPeriodDate);
return tripPatternForDate != null ? new ArrayList<>(tripPatternForDate) : new ArrayList<>();
}

public List<TripPatternForDate> getTripPatternsStartingOnDateCopy(LocalDate date) {
List<TripPatternForDate> tripPatternsRunningOnDate = getTripPatternsRunningOnDateCopy(date);
return tripPatternsRunningOnDate
/**
* Returns a copy of the list of trip patterns for the given service date. Service date is not
* necessarily the same as any of the trip pattern's running dates.
*/
public List<TripPatternForDate> getTripPatternsOnServiceDateCopy(LocalDate date) {
List<TripPatternForDate> tripPatternsRunningOnDates = getTripPatternsRunningOnDateCopy(date);
// Trip pattern can run only after midnight. Therefore, we need to get the trip pattern's for
// the next running date as well and filter out duplicates.
tripPatternsRunningOnDates.addAll(getTripPatternsRunningOnDateCopy(date.plusDays(1)));
return tripPatternsRunningOnDates
.stream()
.filter(t -> t.getLocalDate().equals(date))
.filter(t -> t.getServiceDate().equals(date))
.distinct()
.collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,36 +43,36 @@ public class TripPatternForDate implements Comparable<TripPatternForDate> {
*/
private final FrequencyEntry[] frequencies;

/** The date for which the filtering was performed. */
private final LocalDate localDate;
/** The service date of the trip pattern. */
private final LocalDate serviceDate;

/**
* The date on which the first trip departs.
* The running date on which the first trip departs. Not necessarily the same as the service date.
*/
private final LocalDate startOfRunningPeriod;

/**
* The date on which the last trip arrives.
* The running date on which the last trip arrives.
*/
private final LocalDate endOfRunningPeriod;

public TripPatternForDate(
RoutingTripPattern tripPattern,
List<TripTimes> tripTimes,
List<FrequencyEntry> frequencies,
LocalDate localDate
LocalDate serviceDate
) {
this.tripPattern = tripPattern;
this.tripTimes = tripTimes.toArray(new TripTimes[0]);
this.frequencies = frequencies.toArray(new FrequencyEntry[0]);
this.localDate = localDate;
this.serviceDate = serviceDate;

// TODO: We expect a pattern only containing trips or frequencies, fix ability to merge
if (hasFrequencies()) {
this.startOfRunningPeriod =
ServiceDateUtils
.asDateTime(
localDate,
serviceDate,
frequencies
.stream()
.mapToInt(frequencyEntry -> frequencyEntry.startTime)
Expand All @@ -84,7 +84,7 @@ public TripPatternForDate(
this.endOfRunningPeriod =
ServiceDateUtils
.asDateTime(
localDate,
serviceDate,
frequencies
.stream()
.mapToInt(frequencyEntry -> frequencyEntry.endTime)
Expand All @@ -96,11 +96,11 @@ public TripPatternForDate(
// These depend on the tripTimes array being sorted
var first = tripTimes.get(0);
this.startOfRunningPeriod =
ServiceDateUtils.asDateTime(localDate, first.getDepartureTime(0)).toLocalDate();
ServiceDateUtils.asDateTime(serviceDate, first.getDepartureTime(0)).toLocalDate();
var last = tripTimes.get(tripTimes.size() - 1);
this.endOfRunningPeriod =
ServiceDateUtils
.asDateTime(localDate, last.getArrivalTime(last.getNumStops() - 1))
.asDateTime(serviceDate, last.getArrivalTime(last.getNumStops() - 1))
.toLocalDate();
assertValidRunningPeriod(startOfRunningPeriod, endOfRunningPeriod, first, last);
}
Expand All @@ -126,18 +126,31 @@ public TripTimes getTripTimes(int i) {
return tripTimes[i];
}

public LocalDate getLocalDate() {
return localDate;
/**
* The service date for which the trip pattern belongs to. Not necessarily the same as the start
* of the running period in cases where the trip pattern only runs after midnight.
*/
public LocalDate getServiceDate() {
return serviceDate;
}

public int numberOfTripSchedules() {
return tripTimes.length;
}

/**
* The start of the running period. This is determined by the first departure time for this
* pattern. Not necessarily the same as the service date if the pattern runs after midnight.
*/
public LocalDate getStartOfRunningPeriod() {
return startOfRunningPeriod;
}

/**
* Returns the running dates. A Trip "runs through" a date if any of its arrivals or departures is
* happening on that date. The same trip pattern can therefore have multiple running dates and
* trip pattern is not required to "run" on its service date.
*/
public List<LocalDate> getRunningPeriodDates() {
// Add one day to ensure last day is included
return startOfRunningPeriod
Expand All @@ -151,14 +164,14 @@ public boolean hasFrequencies() {

@Override
public int compareTo(TripPatternForDate other) {
return localDate.compareTo(other.localDate);
return serviceDate.compareTo(other.serviceDate);
}

@Override
public int hashCode() {
return Objects.hash(
tripPattern,
localDate,
serviceDate,
Arrays.hashCode(tripTimes),
Arrays.hashCode(frequencies)
);
Expand All @@ -176,15 +189,17 @@ public boolean equals(Object o) {

return (
tripPattern.equals(that.tripPattern) &&
localDate.equals(that.localDate) &&
serviceDate.equals(that.serviceDate) &&
Arrays.equals(tripTimes, that.tripTimes) &&
Arrays.equals(frequencies, that.frequencies)
);
}

@Override
public String toString() {
return "TripPatternForDate{" + "tripPattern=" + tripPattern + ", localDate=" + localDate + '}';
return (
"TripPatternForDate{" + "tripPattern=" + tripPattern + ", serviceDate=" + serviceDate + '}'
);
}

@Nullable
Expand Down Expand Up @@ -214,7 +229,7 @@ public TripPatternForDate newWithFilteredTripTimes(Predicate<TripTimes> filter)
return this;
}

return new TripPatternForDate(tripPattern, filteredTripTimes, filteredFrequencies, localDate);
return new TripPatternForDate(tripPattern, filteredTripTimes, filteredFrequencies, serviceDate);
}

private static void assertValidRunningPeriod(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public RaptorBoardOrAlightEvent<T> search(
arrivalTime + headway,
headway,
offset,
pattern.getLocalDate()
pattern.getServiceDate()
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public RaptorBoardOrAlightEvent<T> search(
departureTime - headway,
headway,
offset,
pattern.getLocalDate()
pattern.getServiceDate()
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public void update(

if (!tripPatternsStartingOnDateMapCache.containsKey(date)) {
Map<TripPattern, TripPatternForDate> map = realtimeTransitLayer
.getTripPatternsStartingOnDateCopy(date)
.getTripPatternsOnServiceDateCopy(date)
.stream()
.collect(Collectors.toMap(t -> t.getTripPattern().getPattern(), t -> t));
tripPatternsStartingOnDateMapCache.put(date, map);
Expand Down Expand Up @@ -146,7 +146,7 @@ public void update(
} else {
LOG.debug(
"NEW TripPatternForDate: {} - {}",
newTripPatternForDate.getLocalDate(),
newTripPatternForDate.getServiceDate(),
newTripPatternForDate.getTripPattern().debugInfo()
);
}
Expand Down Expand Up @@ -179,7 +179,7 @@ public void update(
}

for (TripPatternForDate tripPatternForDate : previouslyUsedPatterns) {
if (tripPatternForDate.getLocalDate().equals(date)) {
if (tripPatternForDate.getServiceDate().equals(date)) {
TripPattern pattern = tripPatternForDate.getTripPattern().getPattern();
if (!pattern.isCreatedByRealtimeUpdater()) {
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ static List<TripPatternForDates> merge(
// Calculate offsets per date
int[] offsets = new int[patternsSorted.length];
for (int i = 0; i < patternsSorted.length; i++) {
LocalDate serviceDate = patternsSorted[i].getLocalDate();
LocalDate serviceDate = patternsSorted[i].getServiceDate();
if (offsetCache.containsKey(serviceDate)) {
offsets[i] = offsetCache.get(serviceDate);
} else {
Expand Down Expand Up @@ -185,7 +185,9 @@ private static List<TripPatternForDate> filterActiveTripPatterns(
filter.tripTimesPredicate(tripTimes, filter.hasSubModeFilters());
Predicate<TripTimes> tripTimesWithoutSubmodesPredicate = tripTimes ->
filter.tripTimesPredicate(tripTimes, false);
Collection<TripPatternForDate> tripPatternsForDate = transitLayer.getTripPatternsForDate(date);
Collection<TripPatternForDate> tripPatternsForDate = transitLayer.getTripPatternsForRunningDate(
date
);
List<TripPatternForDate> result = new ArrayList<>(tripPatternsForDate.size());
for (TripPatternForDate p : tripPatternsForDate) {
if (firstDay || p.getStartOfRunningPeriod().equals(date)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ private void findTripTimes() {

if (index < numSchedules) {
this.tripTimes = tripPatternForDate.getTripTimes(index);
this.serviceDate = tripPatternForDate.getLocalDate();
this.serviceDate = tripPatternForDate.getServiceDate();
this.secondsOffset = pattern.tripPatternForDateOffsets(i);
return;
}
Expand Down
Loading
Loading