Skip to content

Commit

Permalink
Merge branch 'fix-late-cancellations' into dev-2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
optionsome committed Mar 26, 2024
2 parents d5e3895 + a3d0e67 commit 0eb0b2a
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 31 deletions.
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

0 comments on commit 0eb0b2a

Please sign in to comment.