From 9d9db266b6272e296dc792eec3a7319258af4731 Mon Sep 17 00:00:00 2001 From: josh-willis-arcadis <168561922+josh-willis-arcadis@users.noreply.github.com> Date: Tue, 12 Nov 2024 12:40:39 -0600 Subject: [PATCH 1/3] feat(SpeedTripValidator): add check for duplicate arrival_times for a trip --- src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java | 1 + .../com/conveyal/gtfs/validator/SpeedTripValidator.java | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java b/src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java index 274661274..1b33bbd3f 100644 --- a/src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java +++ b/src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java @@ -28,6 +28,7 @@ public enum NewGTFSErrorType { FREQUENCY_PERIOD_OVERLAP(Priority.MEDIUM, "A frequency for a trip overlaps with another frequency defined for the same trip."), ILLEGAL_FIELD_VALUE(Priority.MEDIUM, "Fields may not contain tabs, carriage returns or new lines."), INTEGER_FORMAT(Priority.MEDIUM, "Incorrect integer format."), + INVALID_ARRIVAL_TIME(Priority.MEDIUM, "Arrival time at current stop is equal to the previous stop, which is impossible."), LANGUAGE_FORMAT(Priority.LOW, "Language should be specified with a valid BCP47 tag."), MISSING_ARRIVAL_OR_DEPARTURE(Priority.MEDIUM, "First and last stop times are required to have both an arrival and departure time."), MISSING_COLUMN(Priority.MEDIUM, "A required column was missing from a table."), diff --git a/src/main/java/com/conveyal/gtfs/validator/SpeedTripValidator.java b/src/main/java/com/conveyal/gtfs/validator/SpeedTripValidator.java index 9a15d17f3..a3b9e7bb0 100644 --- a/src/main/java/com/conveyal/gtfs/validator/SpeedTripValidator.java +++ b/src/main/java/com/conveyal/gtfs/validator/SpeedTripValidator.java @@ -48,8 +48,12 @@ public void validateTrip(Trip trip, Route route, List stopTimes, List< double distanceMeters = 0; for (int i = beginIndex + 1; i < stopTimes.size(); i++) { StopTime currStopTime = stopTimes.get(i); + // Additional check: Ensure arrival_time is not the same for consecutive stops + if (currStopTime.arrival_time == prevStopTime.arrival_time) { + registerError(currStopTime, NewGTFSErrorType.INVALID_ARRIVAL_TIME); + } if (currStopTime.pickup_type == 1 && currStopTime.drop_off_type == 1 && currStopTime.timepoint == 0) { - // stop_time allows neither pickup or drop off and is not a timepoint, so it serves no purpose. + // stop_time allows neither pickup nor drop off and is not a timepoint, so it serves no purpose. registerError(currStopTime, NewGTFSErrorType.STOP_TIME_UNUSED); } Stop currStop = stops.get(i); From d930b01d119dbcea4dea0471c9d0fe2279a97d40 Mon Sep 17 00:00:00 2001 From: josh-willis-arcadis <168561922+josh-willis-arcadis@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:59:13 -0600 Subject: [PATCH 2/3] feat(SpeedTripValidatorTest): first attempt to write test for duplicate arrival_time --- .../com/conveyal/gtfs/validator/SpeedTripValidatorTest.java | 6 ++++-- .../VTA-gtfs-multiple-trips/stop_times.txt | 4 +++- .../real-world-gtfs-feeds/VTA-gtfs-multiple-trips/trips.txt | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/conveyal/gtfs/validator/SpeedTripValidatorTest.java b/src/test/java/com/conveyal/gtfs/validator/SpeedTripValidatorTest.java index b2844cd06..49d33d248 100644 --- a/src/test/java/com/conveyal/gtfs/validator/SpeedTripValidatorTest.java +++ b/src/test/java/com/conveyal/gtfs/validator/SpeedTripValidatorTest.java @@ -12,8 +12,7 @@ import static com.conveyal.gtfs.GTFS.load; import static com.conveyal.gtfs.GTFS.validate; import static com.conveyal.gtfs.TestUtils.assertThatSqlCountQueryYieldsExpectedCount; -import static com.conveyal.gtfs.error.NewGTFSErrorType.TRAVEL_TOO_FAST; -import static com.conveyal.gtfs.error.NewGTFSErrorType.TRAVEL_TOO_SLOW; +import static com.conveyal.gtfs.error.NewGTFSErrorType.*; /** * Distances recorded against each unit test have been produced using the lat/lon values from @@ -112,6 +111,9 @@ public void tripTravelingTooSlowWithMissingStopTimesHasError() { checkFeedHasError(TRAVEL_TOO_SLOW, "6", 3); } + @Test + public void tripHasDuplicateArrivalTimesHasError(){checkFeedHasError(INVALID_ARRIVAL_TIME,"7",2);} + /** * Check that the test feed has exactly one error for the given type, entityId, and entitySequence. */ diff --git a/src/test/resources/real-world-gtfs-feeds/VTA-gtfs-multiple-trips/stop_times.txt b/src/test/resources/real-world-gtfs-feeds/VTA-gtfs-multiple-trips/stop_times.txt index 8a875cb93..503351f3a 100644 --- a/src/test/resources/real-world-gtfs-feeds/VTA-gtfs-multiple-trips/stop_times.txt +++ b/src/test/resources/real-world-gtfs-feeds/VTA-gtfs-multiple-trips/stop_times.txt @@ -23,4 +23,6 @@ trip_id,arrival_time,departure_time,stop_id,stop_sequence,stop_headsign,pickup_t 5,23:59:00,23:59:00,1562,3,,0,0,9.39290047,0 6,00:00:00,00:00:00,4957,1,,0,0,,1 6,,,1558,2,,0,0,8.34879971,0 -6,23:59:00,23:59:00,1562,3,,0,0,9.39290047,0 \ No newline at end of file +6,23:59:00,23:59:00,1562,3,,0,0,9.39290047,0 +7,18000,18000,4957,1,,0,0,,0 +7,18000,18000,1558,2,,0,0,8.34879971,0 \ No newline at end of file diff --git a/src/test/resources/real-world-gtfs-feeds/VTA-gtfs-multiple-trips/trips.txt b/src/test/resources/real-world-gtfs-feeds/VTA-gtfs-multiple-trips/trips.txt index 0e7afa8b6..fea58ec48 100644 --- a/src/test/resources/real-world-gtfs-feeds/VTA-gtfs-multiple-trips/trips.txt +++ b/src/test/resources/real-world-gtfs-feeds/VTA-gtfs-multiple-trips/trips.txt @@ -5,3 +5,4 @@ route_id,service_id,trip_id,trip_headsign,trip_short_name,direction_id,block_id, 23,1,4,PALO ALTO TRANSIT CTR 4,,1,2145,101395,0,0 23,1,5,PALO ALTO TRANSIT CTR 5,,1,2145,101395,0,0 23,1,6,PALO ALTO TRANSIT CTR 6,,1,2145,101395,0,0 +23,1,7,PALO ALTO TRANSIT CTR 7,,1,2145,101395,0,0 \ No newline at end of file From 9fbdaa9c97acaccdd793e5f7e53da0243290f9b7 Mon Sep 17 00:00:00 2001 From: josh-willis-arcadis <168561922+josh-willis-arcadis@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:52:34 -0600 Subject: [PATCH 3/3] refactor: address PR feedback --- src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java | 2 +- .../java/com/conveyal/gtfs/validator/SpeedTripValidator.java | 2 +- .../com/conveyal/gtfs/validator/SpeedTripValidatorTest.java | 4 +++- .../VTA-gtfs-multiple-trips/stop_times.txt | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java b/src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java index 1b33bbd3f..80a9ea244 100644 --- a/src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java +++ b/src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java @@ -28,7 +28,6 @@ public enum NewGTFSErrorType { FREQUENCY_PERIOD_OVERLAP(Priority.MEDIUM, "A frequency for a trip overlaps with another frequency defined for the same trip."), ILLEGAL_FIELD_VALUE(Priority.MEDIUM, "Fields may not contain tabs, carriage returns or new lines."), INTEGER_FORMAT(Priority.MEDIUM, "Incorrect integer format."), - INVALID_ARRIVAL_TIME(Priority.MEDIUM, "Arrival time at current stop is equal to the previous stop, which is impossible."), LANGUAGE_FORMAT(Priority.LOW, "Language should be specified with a valid BCP47 tag."), MISSING_ARRIVAL_OR_DEPARTURE(Priority.MEDIUM, "First and last stop times are required to have both an arrival and departure time."), MISSING_COLUMN(Priority.MEDIUM, "A required column was missing from a table."), @@ -44,6 +43,7 @@ public enum NewGTFSErrorType { NUMBER_TOO_SMALL(Priority.MEDIUM, "Number was below the allowed range."), OVERLAPPING_TRIP(Priority.MEDIUM, "Blocks?"), REFERENTIAL_INTEGRITY(Priority.HIGH, "This line references an ID that does not exist in the target table."), + REPEATED_ARRIVAL_TIME(Priority.MEDIUM, "Arrival time at current stop is equal to the previous stop."), REQUIRED_TABLE_EMPTY(Priority.MEDIUM, "This table is required by the GTFS specification but is empty."), ROUTE_DESCRIPTION_SAME_AS_NAME(Priority.LOW, "The description of a route is identical to its name, so does not add any information."), ROUTE_LONG_NAME_CONTAINS_SHORT_NAME(Priority.LOW, "The long name of a route should complement the short name, not include it."), diff --git a/src/main/java/com/conveyal/gtfs/validator/SpeedTripValidator.java b/src/main/java/com/conveyal/gtfs/validator/SpeedTripValidator.java index a3b9e7bb0..bcecdf7a5 100644 --- a/src/main/java/com/conveyal/gtfs/validator/SpeedTripValidator.java +++ b/src/main/java/com/conveyal/gtfs/validator/SpeedTripValidator.java @@ -50,7 +50,7 @@ public void validateTrip(Trip trip, Route route, List stopTimes, List< StopTime currStopTime = stopTimes.get(i); // Additional check: Ensure arrival_time is not the same for consecutive stops if (currStopTime.arrival_time == prevStopTime.arrival_time) { - registerError(currStopTime, NewGTFSErrorType.INVALID_ARRIVAL_TIME); + registerError(currStopTime, NewGTFSErrorType.REPEATED_ARRIVAL_TIME); } if (currStopTime.pickup_type == 1 && currStopTime.drop_off_type == 1 && currStopTime.timepoint == 0) { // stop_time allows neither pickup nor drop off and is not a timepoint, so it serves no purpose. diff --git a/src/test/java/com/conveyal/gtfs/validator/SpeedTripValidatorTest.java b/src/test/java/com/conveyal/gtfs/validator/SpeedTripValidatorTest.java index 49d33d248..ba960c058 100644 --- a/src/test/java/com/conveyal/gtfs/validator/SpeedTripValidatorTest.java +++ b/src/test/java/com/conveyal/gtfs/validator/SpeedTripValidatorTest.java @@ -112,7 +112,9 @@ public void tripTravelingTooSlowWithMissingStopTimesHasError() { } @Test - public void tripHasDuplicateArrivalTimesHasError(){checkFeedHasError(INVALID_ARRIVAL_TIME,"7",2);} + public void tripHasDuplicateArrivalTimesHasError() { + checkFeedHasError(REPEATED_ARRIVAL_TIME,"7",2); + } /** * Check that the test feed has exactly one error for the given type, entityId, and entitySequence. diff --git a/src/test/resources/real-world-gtfs-feeds/VTA-gtfs-multiple-trips/stop_times.txt b/src/test/resources/real-world-gtfs-feeds/VTA-gtfs-multiple-trips/stop_times.txt index 503351f3a..8215a7c9b 100644 --- a/src/test/resources/real-world-gtfs-feeds/VTA-gtfs-multiple-trips/stop_times.txt +++ b/src/test/resources/real-world-gtfs-feeds/VTA-gtfs-multiple-trips/stop_times.txt @@ -24,5 +24,5 @@ trip_id,arrival_time,departure_time,stop_id,stop_sequence,stop_headsign,pickup_t 6,00:00:00,00:00:00,4957,1,,0,0,,1 6,,,1558,2,,0,0,8.34879971,0 6,23:59:00,23:59:00,1562,3,,0,0,9.39290047,0 -7,18000,18000,4957,1,,0,0,,0 -7,18000,18000,1558,2,,0,0,8.34879971,0 \ No newline at end of file +7,01:00:00,01:00:00,4957,1,,0,0,,0 +7,01:00:00,01:00:00,1558,2,,0,0,8.34879971,0 \ No newline at end of file