Skip to content

Commit 520941f

Browse files
committed
gtfs: rt should work with overdetermined trip descriptors
1 parent a0c1d9c commit 520941f

File tree

2 files changed

+45
-19
lines changed

2 files changed

+45
-19
lines changed

reader-gtfs/src/main/java/com/graphhopper/gtfs/RealtimeFeed.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ private static int[] findLeaveEdgesForTrip(GtfsStorage staticGtfs, String feedKe
179179
.flatMap(e -> StreamSupport.stream(staticGtfs.getPtGraph().backEdgesAround(e.getAdjNode()).spliterator(), false))
180180
.flatMap(e -> StreamSupport.stream(staticGtfs.getPtGraph().backEdgesAround(e.getAdjNode()).spliterator(), false))
181181
.filter(e -> e.getType() == GtfsStorage.EdgeType.ALIGHT)
182-
.filter(e -> normalize(e.getAttrs().tripDescriptor).equals(tripUpdate.getTrip()))
182+
.filter(e -> isDescribedBy(e.getAttrs().tripDescriptor, tripUpdate.getTrip()))
183183
.min(Comparator.comparingInt(e -> e.getAttrs().stop_sequence));
184184
if (firstAlighting.isEmpty()) {
185185
return null;
@@ -198,7 +198,7 @@ private static int[] findBoardEdgesForTrip(GtfsStorage staticGtfs, String feedKe
198198
.flatMap(e -> StreamSupport.stream(staticGtfs.getPtGraph().edgesAround(e.getAdjNode()).spliterator(), false))
199199
.flatMap(e -> StreamSupport.stream(staticGtfs.getPtGraph().edgesAround(e.getAdjNode()).spliterator(), false))
200200
.filter(e -> e.getType() == GtfsStorage.EdgeType.BOARD)
201-
.filter(e -> normalize(e.getAttrs().tripDescriptor).equals(tripUpdate.getTrip()))
201+
.filter(e -> isDescribedBy(e.getAttrs().tripDescriptor, tripUpdate.getTrip()))
202202
.min(Comparator.comparingInt(e -> e.getAttrs().stop_sequence));
203203
if (firstBoarding.isEmpty()) {
204204
return null;
@@ -209,6 +209,18 @@ private static int[] findBoardEdgesForTrip(GtfsStorage staticGtfs, String feedKe
209209
return collectWithPadding(boardEdges);
210210
}
211211

212+
private static boolean isDescribedBy(GtfsRealtime.TripDescriptor a, GtfsRealtime.TripDescriptor b) {
213+
// a is a descriptor of a trip in our database, static or realtime
214+
// b is a descriptor of a trip in a trip update in the literal current rt feed
215+
if (a.hasTripId() && !a.getTripId().equals(b.getTripId())) {
216+
return false;
217+
}
218+
if (a.hasStartTime() && !a.getStartTime().equals(b.getStartTime())) {
219+
return false;
220+
}
221+
return true;
222+
}
223+
212224
private static int[] collectWithPadding(Stream<PtGraph.PtEdge> boardEdges) {
213225
IntArrayList result = new IntArrayList();
214226
boardEdges.forEach(boardEdge -> {
@@ -280,17 +292,16 @@ SortedSet<PtGraph.PtEdge> getAdditionalEdgesTo(int node) {
280292
return additionalEdgesByAdjNode.subSet(new PtGraph.PtEdge(0, 0, node, null), new PtGraph.PtEdge(0, 0, node+1, null));
281293
}
282294

283-
public Optional<GtfsReader.TripWithStopTimes> getTripUpdate(GTFSFeed staticFeed, GtfsRealtime.TripDescriptor tripDescriptor, Instant boardTime) {
295+
public Optional<GtfsReader.TripWithStopTimes> getTripUpdate(GTFSFeed staticFeed, GtfsRealtime.TripDescriptor trip, Instant boardTime) {
284296
try {
285-
logger.trace("getTripUpdate {}", tripDescriptor);
297+
logger.trace("getTripUpdate {}", trip);
286298
if (!isThisRealtimeUpdateAboutThisLineRun(boardTime)) {
287299
return Optional.empty();
288300
} else {
289-
GtfsRealtime.TripDescriptor normalizedTripDescriptor = normalize(tripDescriptor);
290301
return feedMessages.values().stream().flatMap(feedMessage -> feedMessage.getEntityList().stream()
291302
.filter(e -> e.hasTripUpdate())
292303
.map(e -> e.getTripUpdate())
293-
.filter(tu -> normalize(tu.getTrip()).equals(normalizedTripDescriptor))
304+
.filter(tu -> isDescribedBy(trip, tu.getTrip()))
294305
.map(tu -> toTripWithStopTimes(staticFeed, tu)))
295306
.findFirst();
296307
}
@@ -306,10 +317,6 @@ public Optional<GtfsReader.TripWithStopTimes> getTripUpdate(GTFSFeed staticFeed,
306317
}
307318
}
308319

309-
public static GtfsRealtime.TripDescriptor normalize(GtfsRealtime.TripDescriptor tripDescriptor) {
310-
return GtfsRealtime.TripDescriptor.newBuilder(tripDescriptor).clearRouteId().build();
311-
}
312-
313320
public static GtfsReader.TripWithStopTimes toTripWithStopTimes(GTFSFeed feed, GtfsRealtime.TripUpdate tripUpdate) {
314321
ZoneId timezone = ZoneId.of(feed.agency.values().stream().findFirst().get().agency_timezone);
315322
logger.trace("{}", tripUpdate.getTrip());

reader-gtfs/src/test/java/com/graphhopper/RealtimeIT.java

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -707,14 +707,6 @@ public void testMissedTransferBecauseOfDelayBackwards() {
707707

708708
@Test
709709
public void testDelayAtEndForNonFrequencyBasedTrip() {
710-
final double FROM_LAT = 36.915682, FROM_LON = -116.751677; // STAGECOACH stop
711-
final double TO_LAT = 36.88108, TO_LON = -116.81797; // BULLFROG stop
712-
Request ghRequest = new Request(
713-
FROM_LAT, FROM_LON,
714-
TO_LAT, TO_LON
715-
);
716-
ghRequest.setEarliestDepartureTime(LocalDateTime.of(2007, 1, 1, 0, 0).atZone(zoneId).toInstant());
717-
718710
final GtfsRealtime.FeedMessage.Builder feedMessageBuilder = GtfsRealtime.FeedMessage.newBuilder();
719711
feedMessageBuilder.setHeader(header());
720712
feedMessageBuilder.addEntityBuilder()
@@ -725,8 +717,20 @@ public void testDelayAtEndForNonFrequencyBasedTrip() {
725717
.setStopSequence(2)
726718
.setScheduleRelationship(SCHEDULED)
727719
.setArrival(GtfsRealtime.TripUpdate.StopTimeEvent.newBuilder().setDelay(300).build());
720+
GtfsRealtime.FeedMessage feedMessage = feedMessageBuilder.build();
721+
checkDelayAtEnd(feedMessage);
722+
}
728723

729-
PtRouter graphHopper = graphHopperFactory.createWith(feedMessageBuilder.build());
724+
private static void checkDelayAtEnd(GtfsRealtime.FeedMessage feedMessage) {
725+
final double FROM_LAT = 36.915682, FROM_LON = -116.751677; // STAGECOACH stop
726+
final double TO_LAT = 36.88108, TO_LON = -116.81797; // BULLFROG stop
727+
Request ghRequest = new Request(
728+
FROM_LAT, FROM_LON,
729+
TO_LAT, TO_LON
730+
);
731+
ghRequest.setEarliestDepartureTime(LocalDateTime.of(2007, 1, 1, 0, 0).atZone(zoneId).toInstant());
732+
733+
PtRouter graphHopper = graphHopperFactory.createWith(feedMessage);
730734
GHResponse route = graphHopper.route(ghRequest);
731735

732736
assertFalse(route.hasErrors());
@@ -738,6 +742,21 @@ public void testDelayAtEndForNonFrequencyBasedTrip() {
738742
assertEquals(250, route.getBest().getFare().multiply(BigDecimal.valueOf(100)).intValue(), "Paid expected fare"); // Two legs, no transfers allowed. Need two 'p' tickets costing 125 cents each.
739743
}
740744

745+
@Test
746+
public void testDelayAtEndForNonFrequencyBasedTripWithOverdeterminedDescriptor() {
747+
final GtfsRealtime.FeedMessage.Builder feedMessageBuilder = GtfsRealtime.FeedMessage.newBuilder();
748+
feedMessageBuilder.setHeader(header());
749+
feedMessageBuilder.addEntityBuilder()
750+
.setId("1")
751+
.getTripUpdateBuilder()
752+
.setTrip(GtfsRealtime.TripDescriptor.newBuilder().setTripId("AB1").setStartTime("08:00:00"))
753+
.addStopTimeUpdateBuilder()
754+
.setStopSequence(2)
755+
.setScheduleRelationship(SCHEDULED)
756+
.setArrival(GtfsRealtime.TripUpdate.StopTimeEvent.newBuilder().setDelay(300).build());
757+
GtfsRealtime.FeedMessage feedMessage = feedMessageBuilder.build();
758+
checkDelayAtEnd(feedMessage);
759+
}
741760

742761
public GtfsRealtime.FeedHeader.Builder header() {
743762
return GtfsRealtime.FeedHeader.newBuilder()

0 commit comments

Comments
 (0)