From 5f063b9cb160b07e610bf2ab6f758ca2b0fbcb4b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 11 Jun 2026 17:13:17 +0200 Subject: [PATCH 1/2] Match frequency based vehicle --- .../RealtimeVehiclePatternMatcher.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java b/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java index 8e4a3ace823..b4890f9deab 100644 --- a/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java @@ -18,7 +18,9 @@ import java.time.Duration; import java.time.Instant; import java.time.LocalDate; +import java.time.LocalTime; import java.time.ZoneId; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -36,7 +38,9 @@ import org.opentripplanner.street.geometry.WgsCoordinate; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.transit.model.timetable.FrequencyEntry; import org.opentripplanner.transit.model.timetable.OccupancyStatus; +import org.opentripplanner.transit.model.timetable.Timetable; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.updater.spi.ResultLogger; @@ -382,10 +386,21 @@ private PatternAndRealtimeVehicle toRealtimeVehicle( throw UpdateException.of(scopedTripId, NO_SERVICE_ON_DATE); } + var scheduledTimetable = getStaticPattern.apply(trip).getScheduledTimetable(); // the trip times are only used for mapping the GTFS-RT stop_sequence back to a stop. // because new trips without trip times are created for realtime-updated ones, we explicitly // look at the static trips for the stop_sequence->stop mapping - var staticTripTimes = getStaticPattern.apply(trip).getScheduledTimetable().getTripTimes(trip); + var staticTripTimes = scheduledTimetable.getTripTimes(trip); + + if(!scheduledTimetable.getFrequencyEntries().isEmpty() && vehiclePosition.getTrip().hasStartDate()){ + var updateStartTime = LocalTime.parse(vehiclePosition.getTrip().getStartTime()); + staticTripTimes = scheduledTimetable.getFrequencyEntries().stream().map(FrequencyEntry::tripTimes).filter(e -> { + var start = e.getScheduledDepartureTime(0); + var startTime = LocalTime.ofSecondOfDay(start).truncatedTo(ChronoUnit.MINUTES); + return updateStartTime.equals(startTime); + }).findFirst().orElse(null); + } + if (staticTripTimes == null) { throw UpdateException.of(scopedTripId, TRIP_NOT_FOUND_IN_PATTERN); } From c8ed354d016aac2601787e6e8bb93b45d672161c Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 12 Jun 2026 08:10:14 +0200 Subject: [PATCH 2/2] Fix import --- .../RealtimeVehiclePatternMatcher.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java b/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java index b4890f9deab..832af758bb5 100644 --- a/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java +++ b/application/src/main/java/org/opentripplanner/updater/vehicle_position/RealtimeVehiclePatternMatcher.java @@ -40,7 +40,6 @@ import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.FrequencyEntry; import org.opentripplanner.transit.model.timetable.OccupancyStatus; -import org.opentripplanner.transit.model.timetable.Timetable; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.updater.spi.ResultLogger; @@ -392,13 +391,22 @@ private PatternAndRealtimeVehicle toRealtimeVehicle( // look at the static trips for the stop_sequence->stop mapping var staticTripTimes = scheduledTimetable.getTripTimes(trip); - if(!scheduledTimetable.getFrequencyEntries().isEmpty() && vehiclePosition.getTrip().hasStartDate()){ + if ( + !scheduledTimetable.getFrequencyEntries().isEmpty() && + vehiclePosition.getTrip().hasStartDate() + ) { var updateStartTime = LocalTime.parse(vehiclePosition.getTrip().getStartTime()); - staticTripTimes = scheduledTimetable.getFrequencyEntries().stream().map(FrequencyEntry::tripTimes).filter(e -> { - var start = e.getScheduledDepartureTime(0); - var startTime = LocalTime.ofSecondOfDay(start).truncatedTo(ChronoUnit.MINUTES); - return updateStartTime.equals(startTime); - }).findFirst().orElse(null); + staticTripTimes = scheduledTimetable + .getFrequencyEntries() + .stream() + .map(FrequencyEntry::tripTimes) + .filter(e -> { + var start = e.getScheduledDepartureTime(0); + var startTime = LocalTime.ofSecondOfDay(start).truncatedTo(ChronoUnit.MINUTES); + return updateStartTime.equals(startTime); + }) + .findFirst() + .orElse(null); } if (staticTripTimes == null) {