From 9a65a99e81b32d68fc6e59bb74a3f9508271c6bd Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Wed, 8 May 2024 07:26:57 +0300 Subject: [PATCH 01/35] Remove duplicate of feedImpl typeWiring --- .../java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index 1fd78765a07..53d53b9bc4b 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -129,7 +129,6 @@ protected static GraphQLSchema buildSchema() { .type(typeWiring.build(DepartureRowImpl.class)) .type(typeWiring.build(elevationProfileComponentImpl.class)) .type(typeWiring.build(FeedImpl.class)) - .type(typeWiring.build(FeedImpl.class)) .type(typeWiring.build(GeometryImpl.class)) .type(typeWiring.build(ItineraryImpl.class)) .type(typeWiring.build(LegImpl.class)) From 0ba5df5269168b86cf5819e94d45fe895135970a Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Wed, 8 May 2024 07:28:57 +0300 Subject: [PATCH 02/35] Data fetchers for publisherName and publisherUrl of FeedInfo class --- .../apis/gtfs/datafetchers/FeedImpl.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java index 7d7c62136b6..6cf8d27b262 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java @@ -64,6 +64,22 @@ public DataFetcher feedId() { return this::getSource; } + @Override + public DataFetcher publisherName() { + return environment -> { + String id = getSource(environment); + return getTransitService(environment).getFeedInfo(id).getPublisherName(); + }; + } + + @Override + public DataFetcher publisherUrl() { + return environment -> { + String id = getSource(environment); + return getTransitService(environment).getFeedInfo(id).getPublisherUrl(); + }; + } + private List getAgencies(DataFetchingEnvironment environment) { String id = getSource(environment); return getTransitService(environment) From c43b8d56ecaab1a164500f6fd16d4add58a04669 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Wed, 8 May 2024 07:30:59 +0300 Subject: [PATCH 03/35] Update gtfs graphql schema --- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 56f3528d6e3..b81ebdff4c7 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -984,6 +984,12 @@ type Feed { """List of agencies which provide data to this feed""" agencies: [Agency] + """Name of feed publisher""" + publisherName: String! + + """Web address of feed publisher""" + publisherUrl: String! + """ Alerts relevant for the feed. """ From 4b9b06592b2c433357d637683d45e7ae96682a93 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Wed, 8 May 2024 07:49:16 +0300 Subject: [PATCH 04/35] Update generated GraphQLDataFetchers.java --- .../apis/gtfs/generated/GraphQLDataFetchers.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index 559acac920d..6a2e398cd91 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -380,6 +380,10 @@ public interface GraphQLFeed { public DataFetcher> alerts(); public DataFetcher feedId(); + + public DataFetcher publisherName(); + + public DataFetcher publisherUrl(); } public interface GraphQLGeometry { From 119927ea79af4a4ee511de71309da9d29a30f140 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Wed, 8 May 2024 12:43:55 +0300 Subject: [PATCH 05/35] Add test for feedinfo query --- .../apis/gtfs/GraphQLIntegrationTest.java | 14 ++++++++++++++ .../apis/gtfs/expectations/feedinfo.json | 16 ++++++++++++++++ .../apis/gtfs/queries/feedinfo.graphql | 10 ++++++++++ 3 files changed, 40 insertions(+) create mode 100644 src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json create mode 100644 src/test/resources/org/opentripplanner/apis/gtfs/queries/feedinfo.graphql diff --git a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java b/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java index fcc59af845f..614c8778c6b 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java +++ b/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java @@ -43,6 +43,7 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.framework.model.Grams; +import org.opentripplanner.model.FeedInfo; import org.opentripplanner.model.fare.FareMedium; import org.opentripplanner.model.fare.FareProduct; import org.opentripplanner.model.fare.ItineraryFares; @@ -84,6 +85,7 @@ import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.BikeAccess; import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.RealTimeTripTimes; @@ -151,6 +153,18 @@ static void setup() { transitModel.addTripPattern(id("pattern-1"), pattern); + var feedId = "testfeed"; + var feedInfo = FeedInfo.dummyForTest(feedId); + transitModel.addFeedInfo(feedInfo); + + var agency = Agency + .of(new FeedScopedId(feedId, "agency-xx")) + .withName("speedtransit") + .withUrl("www.otp-foo.bar") + .withTimezone("Europe/Berlin") + .build(); + transitModel.addAgency(agency); + transitModel.initTimeZone(ZoneIds.BERLIN); transitModel.index(); var routes = Arrays diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json new file mode 100644 index 00000000000..a3dbe43b0f1 --- /dev/null +++ b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json @@ -0,0 +1,16 @@ +{ + "data" : { + "feeds" : [ + { + "agencies" : [ + { + "name" : "speedtransit", + "url" : "www.otp-foo.bar" + } + ], + "publisherUrl" : "www.z.org", + "publisherName" : "publisher" + } + ] + } +} \ No newline at end of file diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/feedinfo.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/feedinfo.graphql new file mode 100644 index 00000000000..f0737202786 --- /dev/null +++ b/src/test/resources/org/opentripplanner/apis/gtfs/queries/feedinfo.graphql @@ -0,0 +1,10 @@ +{ + feeds { + agencies { + name + url + } + publisherUrl + publisherName + } +} \ No newline at end of file From 659c9bee44724781fd5b58b673c47ca48fd4845a Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Tue, 14 May 2024 16:02:59 +0300 Subject: [PATCH 06/35] Collect feed info publisher data into object --- .../apis/gtfs/datafetchers/FeedImpl.java | 16 ++++++---------- .../gtfs/generated/GraphQLDataFetchers.java | 9 +++++++-- .../model/organization/FeedPublisher.java | 10 ++++++++++ .../opentripplanner/apis/gtfs/schema.graphqls | 19 ++++++++++++++----- .../apis/gtfs/expectations/feedinfo.json | 6 ++++-- .../apis/gtfs/queries/feedinfo.graphql | 6 ++++-- 6 files changed, 45 insertions(+), 21 deletions(-) create mode 100644 src/main/java/org/opentripplanner/transit/model/organization/FeedPublisher.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java index 6cf8d27b262..47b0fc7e106 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java @@ -13,6 +13,7 @@ import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.transit.model.organization.Agency; +import org.opentripplanner.transit.model.organization.FeedPublisher; import org.opentripplanner.transit.service.TransitService; public class FeedImpl implements GraphQLDataFetchers.GraphQLFeed { @@ -65,18 +66,13 @@ public DataFetcher feedId() { } @Override - public DataFetcher publisherName() { + public DataFetcher publisher() { return environment -> { String id = getSource(environment); - return getTransitService(environment).getFeedInfo(id).getPublisherName(); - }; - } - - @Override - public DataFetcher publisherUrl() { - return environment -> { - String id = getSource(environment); - return getTransitService(environment).getFeedInfo(id).getPublisherUrl(); + return new FeedPublisher( + getTransitService(environment).getFeedInfo(id).getPublisherName(), + getTransitService(environment).getFeedInfo(id).getPublisherUrl() + ); }; } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index 6a2e398cd91..455503ad8ef 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -381,9 +381,14 @@ public interface GraphQLFeed { public DataFetcher feedId(); - public DataFetcher publisherName(); + public DataFetcher publisher(); + } + + /** Feed publisher information */ + public interface GraphQLFeedPublisher { + public DataFetcher name(); - public DataFetcher publisherUrl(); + public DataFetcher url(); } public interface GraphQLGeometry { diff --git a/src/main/java/org/opentripplanner/transit/model/organization/FeedPublisher.java b/src/main/java/org/opentripplanner/transit/model/organization/FeedPublisher.java new file mode 100644 index 00000000000..6c9a120e81b --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/model/organization/FeedPublisher.java @@ -0,0 +1,10 @@ +package org.opentripplanner.transit.model.organization; + +import java.util.Objects; + +public record FeedPublisher(String name, String url) { + public FeedPublisher { + Objects.requireNonNull(name); + Objects.requireNonNull(url); + } +} diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index b81ebdff4c7..15de75f5408 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -974,6 +974,18 @@ type fareComponent { routes: [Route] @deprecated } + +""" +Feed publisher information +""" +type FeedPublisher { + """Name of feed publisher""" + name: String! + + """Web address of feed publisher""" + url: String! +} + """ A feed provides routing data (stops, routes, timetables, etc.) from one or more public transport agencies. """ @@ -984,11 +996,8 @@ type Feed { """List of agencies which provide data to this feed""" agencies: [Agency] - """Name of feed publisher""" - publisherName: String! - - """Web address of feed publisher""" - publisherUrl: String! + """publisher""" + publisher: FeedPublisher! """ Alerts relevant for the feed. diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json index a3dbe43b0f1..3cf3bd06d66 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json +++ b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/feedinfo.json @@ -8,8 +8,10 @@ "url" : "www.otp-foo.bar" } ], - "publisherUrl" : "www.z.org", - "publisherName" : "publisher" + "publisher" : { + "name" : "publisher", + "url" : "www.z.org" + } } ] } diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/feedinfo.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/feedinfo.graphql index f0737202786..68516d26237 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/feedinfo.graphql +++ b/src/test/resources/org/opentripplanner/apis/gtfs/queries/feedinfo.graphql @@ -4,7 +4,9 @@ name url } - publisherUrl - publisherName + publisher { + name + url + } } } \ No newline at end of file From c1d8f5be03a8b802f43ec308a30c32da8aa7cbaf Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Wed, 15 May 2024 08:19:34 +0300 Subject: [PATCH 07/35] Move FeedPublisher class to more suitable directory path --- .../org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java | 2 +- .../model/organization => apis/gtfs/model}/FeedPublisher.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/main/java/org/opentripplanner/{transit/model/organization => apis/gtfs/model}/FeedPublisher.java (76%) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java index 47b0fc7e106..9c5b17a62e2 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java @@ -9,11 +9,11 @@ import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.gtfs.model.FeedPublisher; import org.opentripplanner.routing.alertpatch.EntitySelector; import org.opentripplanner.routing.alertpatch.TransitAlert; import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.transit.model.organization.Agency; -import org.opentripplanner.transit.model.organization.FeedPublisher; import org.opentripplanner.transit.service.TransitService; public class FeedImpl implements GraphQLDataFetchers.GraphQLFeed { diff --git a/src/main/java/org/opentripplanner/transit/model/organization/FeedPublisher.java b/src/main/java/org/opentripplanner/apis/gtfs/model/FeedPublisher.java similarity index 76% rename from src/main/java/org/opentripplanner/transit/model/organization/FeedPublisher.java rename to src/main/java/org/opentripplanner/apis/gtfs/model/FeedPublisher.java index 6c9a120e81b..ba524b537f0 100644 --- a/src/main/java/org/opentripplanner/transit/model/organization/FeedPublisher.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/model/FeedPublisher.java @@ -1,4 +1,4 @@ -package org.opentripplanner.transit.model.organization; +package org.opentripplanner.apis.gtfs.model; import java.util.Objects; From 1fbf5ca42445b6ee3fc483394be8dcfda48a70ba Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 18 May 2024 09:33:54 +0200 Subject: [PATCH 08/35] Finish up renaming duration factor to time penalty --- .../ext/flex/flexpathcalculator/FlexPathTest.java | 4 ++-- .../ext/flex/flexpathcalculator/FlexPath.java | 2 +- .../flex/flexpathcalculator/TimePenaltyCalculator.java | 6 +++--- .../gtfs/mapping/GTFSToOtpTransitServiceMapper.java | 2 +- .../org/opentripplanner/gtfs/mapping/TripMapper.java | 10 +++++----- .../model/impl/OtpTransitServiceBuilder.java | 4 ++-- .../opentripplanner/gtfs/mapping/TripMapperTest.java | 8 ++++---- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java index 8bd3abee785..fca0d22cdf3 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java @@ -30,8 +30,8 @@ static List cases() { @ParameterizedTest @MethodSource("cases") - void calculate(TimePenalty mod, int expectedSeconds) { - var modified = PATH.withDurationModifier(mod); + void calculate(TimePenalty penalty, int expectedSeconds) { + var modified = PATH.withTimePenalty(penalty); assertEquals(expectedSeconds, modified.durationSeconds); assertEquals(LineStrings.SIMPLE, modified.getGeometry()); } diff --git a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java b/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java index 3a692dff40b..0b227490e9d 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java +++ b/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java @@ -41,7 +41,7 @@ public LineString getGeometry() { /** * Returns an (immutable) copy of this path with the duration modified. */ - public FlexPath withDurationModifier(TimePenalty mod) { + public FlexPath withTimePenalty(TimePenalty mod) { if (mod.isZero()) { return this; } else { diff --git a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculator.java b/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculator.java index 63b661f0f9a..4fde3fcfbff 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculator.java +++ b/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculator.java @@ -11,11 +11,11 @@ public class TimePenaltyCalculator implements FlexPathCalculator { private final FlexPathCalculator delegate; - private final TimePenalty factors; + private final TimePenalty penalty; public TimePenaltyCalculator(FlexPathCalculator delegate, TimePenalty penalty) { this.delegate = delegate; - this.factors = penalty; + this.penalty = penalty; } @Nullable @@ -26,7 +26,7 @@ public FlexPath calculateFlexPath(Vertex fromv, Vertex tov, int fromStopIndex, i if (path == null) { return null; } else { - return path.withDurationModifier(factors); + return path.withTimePenalty(penalty); } } } diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/GTFSToOtpTransitServiceMapper.java b/src/main/java/org/opentripplanner/gtfs/mapping/GTFSToOtpTransitServiceMapper.java index ce65d6b0820..354c1f16177 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/GTFSToOtpTransitServiceMapper.java +++ b/src/main/java/org/opentripplanner/gtfs/mapping/GTFSToOtpTransitServiceMapper.java @@ -171,7 +171,7 @@ public void mapStopTripAndRouteDataIntoBuilder() { builder.getPathways().addAll(pathwayMapper.map(data.getAllPathways())); builder.getStopTimesSortedByTrip().addAll(stopTimeMapper.map(data.getAllStopTimes())); - builder.getFlexTimePenalty().putAll(tripMapper.flexSafeDurationModifiers()); + builder.getFlexTimePenalty().putAll(tripMapper.flexSafeTimePenalties()); builder.getTripsById().addAll(tripMapper.map(data.getAllTrips())); fareRulesBuilder.fareAttributes().addAll(fareAttributeMapper.map(data.getAllFareAttributes())); diff --git a/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java b/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java index ca221c1c6ca..3a62ba2b269 100644 --- a/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java +++ b/src/main/java/org/opentripplanner/gtfs/mapping/TripMapper.java @@ -18,7 +18,7 @@ class TripMapper { private final TranslationHelper translationHelper; private final Map mappedTrips = new HashMap<>(); - private final Map flexSafeDurationModifiers = new HashMap<>(); + private final Map flexSafeTimePenalties = new HashMap<>(); TripMapper( RouteMapper routeMapper, @@ -45,8 +45,8 @@ Collection getMappedTrips() { /** * The map of flex duration factors per flex trip. */ - Map flexSafeDurationModifiers() { - return flexSafeDurationModifiers; + Map flexSafeTimePenalties() { + return flexSafeTimePenalties; } private Trip doMap(org.onebusaway.gtfs.model.Trip rhs) { @@ -73,11 +73,11 @@ private Trip doMap(org.onebusaway.gtfs.model.Trip rhs) { lhs.withBikesAllowed(BikeAccessMapper.mapForTrip(rhs)); var trip = lhs.build(); - mapSafeDurationModifier(rhs).ifPresent(f -> flexSafeDurationModifiers.put(trip, f)); + mapSafeTimePenalty(rhs).ifPresent(f -> flexSafeTimePenalties.put(trip, f)); return trip; } - private Optional mapSafeDurationModifier(org.onebusaway.gtfs.model.Trip rhs) { + private Optional mapSafeTimePenalty(org.onebusaway.gtfs.model.Trip rhs) { if (rhs.getSafeDurationFactor() == null && rhs.getSafeDurationOffset() == null) { return Optional.empty(); } else { diff --git a/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceBuilder.java b/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceBuilder.java index 544ca29599d..43c18cec59d 100644 --- a/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceBuilder.java +++ b/src/main/java/org/opentripplanner/model/impl/OtpTransitServiceBuilder.java @@ -94,7 +94,7 @@ public class OtpTransitServiceBuilder { private final TripStopTimes stopTimesByTrip = new TripStopTimes(); - private final Map flexDurationFactors = new HashMap<>(); + private final Map flexTimePenalties = new HashMap<>(); private final EntityById fareZonesById = new DefaultEntityById<>(); @@ -214,7 +214,7 @@ public TripStopTimes getStopTimesSortedByTrip() { } public Map getFlexTimePenalty() { - return flexDurationFactors; + return flexTimePenalties; } public EntityById getFareZonesById() { diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java b/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java index f24e405515d..535ec349fba 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java +++ b/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java @@ -111,14 +111,14 @@ void testMapCache() throws Exception { } @Test - void noFlexDurationModifier() { + void noFlexTimePenalty() { var mapper = defaultTripMapper(); mapper.map(TRIP); - assertTrue(mapper.flexSafeDurationModifiers().isEmpty()); + assertTrue(mapper.flexSafeTimePenalties().isEmpty()); } @Test - void flexDurationModifier() { + void flexTimePenalty() { var flexTrip = new Trip(); flexTrip.setId(new AgencyAndId("1", "1")); flexTrip.setSafeDurationFactor(1.5); @@ -126,7 +126,7 @@ void flexDurationModifier() { flexTrip.setRoute(new GtfsTestData().route); var mapper = defaultTripMapper(); var mapped = mapper.map(flexTrip); - var mod = mapper.flexSafeDurationModifiers().get(mapped); + var mod = mapper.flexSafeTimePenalties().get(mapped); assertEquals(1.5f, mod.coefficient()); assertEquals(600, mod.constant().toSeconds()); } From 0113169c6b7cd2b6c10dcfb6278f4bcfc2734f46 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Sat, 18 May 2024 14:10:26 +0200 Subject: [PATCH 09/35] Add test for default time penalty --- .../ext/flex/FlexTripsMapperTest.java | 30 +++++++++++++++++++ .../flex/flexpathcalculator/FlexPathTest.java | 2 +- .../ext/flex/flexpathcalculator/FlexPath.java | 10 ++----- .../ext/flex/trip/UnscheduledTrip.java | 12 +++++++- 4 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 src/ext-test/java/org/opentripplanner/ext/flex/FlexTripsMapperTest.java diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/FlexTripsMapperTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/FlexTripsMapperTest.java new file mode 100644 index 00000000000..9670bec2802 --- /dev/null +++ b/src/ext-test/java/org/opentripplanner/ext/flex/FlexTripsMapperTest.java @@ -0,0 +1,30 @@ +package org.opentripplanner.ext.flex; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.opentripplanner.graph_builder.issue.api.DataImportIssueStore.NOOP; + +import java.util.List; +import org.junit.jupiter.api.Test; +import org.opentripplanner.model.StopTime; +import org.opentripplanner.model.impl.OtpTransitServiceBuilder; +import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.service.StopModel; + +class FlexTripsMapperTest { + + @Test + void defaultTimePenalty() { + var builder = new OtpTransitServiceBuilder(StopModel.of().build(), NOOP); + var stopTimes = List.of(stopTime(0), stopTime(1)); + builder.getStopTimesSortedByTrip().addAll(stopTimes); + var trips = FlexTripsMapper.createFlexTrips(builder, NOOP); + assertEquals("[UnscheduledTrip{F:flex-1 timePenalty=(0s + 1.00 t)}]", trips.toString()); + } + + private static StopTime stopTime(int seq) { + var st = FlexStopTimesForTest.area("08:00", "18:00"); + st.setTrip(TransitModelForTest.trip("flex-1").build()); + st.setStopSequence(seq); + return st; + } +} diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java index fca0d22cdf3..3d37de02af4 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPathTest.java @@ -21,7 +21,7 @@ class FlexPathTest { static List cases() { return List.of( - Arguments.of(TimePenalty.ZERO, THIRTY_MINS_IN_SECONDS), + Arguments.of(TimePenalty.NONE, THIRTY_MINS_IN_SECONDS), Arguments.of(TimePenalty.of(Duration.ofMinutes(10), 1), 2400), Arguments.of(TimePenalty.of(Duration.ofMinutes(10), 1.5f), 3300), Arguments.of(TimePenalty.of(Duration.ZERO, 3), 5400) diff --git a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java b/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java index 0b227490e9d..4a494286313 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java +++ b/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/FlexPath.java @@ -41,12 +41,8 @@ public LineString getGeometry() { /** * Returns an (immutable) copy of this path with the duration modified. */ - public FlexPath withTimePenalty(TimePenalty mod) { - if (mod.isZero()) { - return this; - } else { - int updatedDuration = (int) mod.calculate(Duration.ofSeconds(durationSeconds)).toSeconds(); - return new FlexPath(distanceMeters, updatedDuration, geometrySupplier); - } + public FlexPath withTimePenalty(TimePenalty penalty) { + int updatedDuration = (int) penalty.calculate(Duration.ofSeconds(durationSeconds)).toSeconds(); + return new FlexPath(distanceMeters, updatedDuration, geometrySupplier); } } diff --git a/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java b/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java index 402d39e2aa7..a14f80d74a4 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java +++ b/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java @@ -14,6 +14,7 @@ import java.util.stream.IntStream; import java.util.stream.Stream; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.opentripplanner.ext.flex.FlexServiceDate; import org.opentripplanner.ext.flex.flexpathcalculator.FlexPathCalculator; import org.opentripplanner.ext.flex.flexpathcalculator.TimePenaltyCalculator; @@ -29,6 +30,7 @@ import org.opentripplanner.routing.graphfinder.NearbyStop; import org.opentripplanner.standalone.config.sandbox.FlexConfig; import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.framework.LogInfo; import org.opentripplanner.transit.model.framework.TransitBuilder; import org.opentripplanner.transit.model.site.GroupStop; import org.opentripplanner.transit.model.site.StopLocation; @@ -45,7 +47,9 @@ *

* For a discussion of this behaviour see https://github.com/MobilityData/gtfs-flex/issues/76 */ -public class UnscheduledTrip extends FlexTrip { +public class UnscheduledTrip + extends FlexTrip + implements LogInfo { private static final Set N_STOPS = Set.of(1, 2); private static final int INDEX_NOT_FOUND = -1; @@ -154,6 +158,12 @@ public Stream getFlexAccessTemplates( ); } + @Nullable + @Override + public String logName() { + return "timePenalty=(%s)".formatted(timePenalty.toString()); + } + /** * Get the correct {@link FlexPathCalculator} depending on the {@code timePenalty}. * If the modifier doesn't actually modify, we return the regular calculator. From 57c4282909bc05ef1eee427954639d780b2e2659 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 22 May 2024 09:21:51 +0200 Subject: [PATCH 10/35] Apply review feedback --- .../ext/flex/flexpathcalculator/TimePenaltyCalculator.java | 4 ++-- .../org/opentripplanner/ext/flex/trip/UnscheduledTrip.java | 2 +- .../routing/api/request/framework/TimePenalty.java | 3 +++ .../org/opentripplanner/gtfs/mapping/TripMapperTest.java | 6 +++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculator.java b/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculator.java index 4fde3fcfbff..a2252f3fec8 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculator.java +++ b/src/ext/java/org/opentripplanner/ext/flex/flexpathcalculator/TimePenaltyCalculator.java @@ -5,8 +5,8 @@ import org.opentripplanner.street.model.vertex.Vertex; /** - * A calculator to delegates the main computation to another instance and applies a duration - * modifier afterward. + * A calculator to delegates the main computation to another instance and applies a time penalty + * afterward. */ public class TimePenaltyCalculator implements FlexPathCalculator { diff --git a/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java b/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java index a14f80d74a4..08c1f9b5d3c 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java +++ b/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java @@ -166,7 +166,7 @@ public String logName() { /** * Get the correct {@link FlexPathCalculator} depending on the {@code timePenalty}. - * If the modifier doesn't actually modify, we return the regular calculator. + * If the penalty would not change the result, we return the regular calculator. */ protected FlexPathCalculator flexPathCalculator(FlexPathCalculator calculator) { if (timePenalty.modifies()) { diff --git a/src/main/java/org/opentripplanner/routing/api/request/framework/TimePenalty.java b/src/main/java/org/opentripplanner/routing/api/request/framework/TimePenalty.java index 0c6fdd96436..3ee07034135 100644 --- a/src/main/java/org/opentripplanner/routing/api/request/framework/TimePenalty.java +++ b/src/main/java/org/opentripplanner/routing/api/request/framework/TimePenalty.java @@ -7,6 +7,9 @@ public final class TimePenalty extends AbstractLinearFunction { public static final TimePenalty ZERO = new TimePenalty(Duration.ZERO, 0.0); + /** + * An instance that doesn't actually apply a penalty and returns the duration unchanged. + */ public static final TimePenalty NONE = new TimePenalty(Duration.ZERO, 1.0); private TimePenalty(Duration constant, double coefficient) { diff --git a/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java b/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java index 535ec349fba..964c3d8155e 100644 --- a/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java +++ b/src/test/java/org/opentripplanner/gtfs/mapping/TripMapperTest.java @@ -126,8 +126,8 @@ void flexTimePenalty() { flexTrip.setRoute(new GtfsTestData().route); var mapper = defaultTripMapper(); var mapped = mapper.map(flexTrip); - var mod = mapper.flexSafeTimePenalties().get(mapped); - assertEquals(1.5f, mod.coefficient()); - assertEquals(600, mod.constant().toSeconds()); + var penalty = mapper.flexSafeTimePenalties().get(mapped); + assertEquals(1.5f, penalty.coefficient()); + assertEquals(600, penalty.constant().toSeconds()); } } From 3faf5916abcea6c2440fcde7054729fcb18c624d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 23 May 2024 17:26:53 +0200 Subject: [PATCH 11/35] Re-implement test by checking the calculator --- .../ext/flex/{ => trip}/FlexTripsMapperTest.java | 11 +++++++++-- .../ext/flex/trip/UnscheduledTrip.java | 12 +----------- 2 files changed, 10 insertions(+), 13 deletions(-) rename src/ext-test/java/org/opentripplanner/ext/flex/{ => trip}/FlexTripsMapperTest.java (62%) diff --git a/src/ext-test/java/org/opentripplanner/ext/flex/FlexTripsMapperTest.java b/src/ext-test/java/org/opentripplanner/ext/flex/trip/FlexTripsMapperTest.java similarity index 62% rename from src/ext-test/java/org/opentripplanner/ext/flex/FlexTripsMapperTest.java rename to src/ext-test/java/org/opentripplanner/ext/flex/trip/FlexTripsMapperTest.java index 9670bec2802..0d0376bbd32 100644 --- a/src/ext-test/java/org/opentripplanner/ext/flex/FlexTripsMapperTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/flex/trip/FlexTripsMapperTest.java @@ -1,10 +1,14 @@ -package org.opentripplanner.ext.flex; +package org.opentripplanner.ext.flex.trip; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.opentripplanner.graph_builder.issue.api.DataImportIssueStore.NOOP; import java.util.List; import org.junit.jupiter.api.Test; +import org.opentripplanner.ext.flex.FlexStopTimesForTest; +import org.opentripplanner.ext.flex.FlexTripsMapper; +import org.opentripplanner.ext.flex.flexpathcalculator.DirectFlexPathCalculator; import org.opentripplanner.model.StopTime; import org.opentripplanner.model.impl.OtpTransitServiceBuilder; import org.opentripplanner.transit.model._data.TransitModelForTest; @@ -18,7 +22,10 @@ void defaultTimePenalty() { var stopTimes = List.of(stopTime(0), stopTime(1)); builder.getStopTimesSortedByTrip().addAll(stopTimes); var trips = FlexTripsMapper.createFlexTrips(builder, NOOP); - assertEquals("[UnscheduledTrip{F:flex-1 timePenalty=(0s + 1.00 t)}]", trips.toString()); + assertEquals("[UnscheduledTrip{F:flex-1}]", trips.toString()); + var unscheduled = (UnscheduledTrip) trips.getFirst(); + var unchanged = unscheduled.flexPathCalculator(new DirectFlexPathCalculator()); + assertInstanceOf(DirectFlexPathCalculator.class, unchanged); } private static StopTime stopTime(int seq) { diff --git a/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java b/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java index 08c1f9b5d3c..a4c8d9568ca 100644 --- a/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java +++ b/src/ext/java/org/opentripplanner/ext/flex/trip/UnscheduledTrip.java @@ -14,7 +14,6 @@ import java.util.stream.IntStream; import java.util.stream.Stream; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import org.opentripplanner.ext.flex.FlexServiceDate; import org.opentripplanner.ext.flex.flexpathcalculator.FlexPathCalculator; import org.opentripplanner.ext.flex.flexpathcalculator.TimePenaltyCalculator; @@ -30,7 +29,6 @@ import org.opentripplanner.routing.graphfinder.NearbyStop; import org.opentripplanner.standalone.config.sandbox.FlexConfig; import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.model.framework.LogInfo; import org.opentripplanner.transit.model.framework.TransitBuilder; import org.opentripplanner.transit.model.site.GroupStop; import org.opentripplanner.transit.model.site.StopLocation; @@ -47,9 +45,7 @@ *

* For a discussion of this behaviour see https://github.com/MobilityData/gtfs-flex/issues/76 */ -public class UnscheduledTrip - extends FlexTrip - implements LogInfo { +public class UnscheduledTrip extends FlexTrip { private static final Set N_STOPS = Set.of(1, 2); private static final int INDEX_NOT_FOUND = -1; @@ -158,12 +154,6 @@ public Stream getFlexAccessTemplates( ); } - @Nullable - @Override - public String logName() { - return "timePenalty=(%s)".formatted(timePenalty.toString()); - } - /** * Get the correct {@link FlexPathCalculator} depending on the {@code timePenalty}. * If the penalty would not change the result, we return the regular calculator. From db9d8748996959aef4bb91062f09aef9f8e20319 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Mon, 27 May 2024 13:32:42 +0300 Subject: [PATCH 12/35] Add FeedPublisher type mapping --- .../org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java | 2 +- .../apis/gtfs/generated/GraphQLDataFetchers.java | 3 ++- .../opentripplanner/apis/gtfs/generated/graphql-codegen.yml | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java index 9c5b17a62e2..d6488d3f375 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/FeedImpl.java @@ -66,7 +66,7 @@ public DataFetcher feedId() { } @Override - public DataFetcher publisher() { + public DataFetcher publisher() { return environment -> { String id = getSource(environment); return new FeedPublisher( diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index 455503ad8ef..fbfc4965c62 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -20,6 +20,7 @@ import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLRelativeDirection; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLRoutingErrorCode; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLTransitMode; +import org.opentripplanner.apis.gtfs.model.FeedPublisher; import org.opentripplanner.apis.gtfs.model.RideHailingProvider; import org.opentripplanner.apis.gtfs.model.StopPosition; import org.opentripplanner.apis.gtfs.model.TripOccupancy; @@ -381,7 +382,7 @@ public interface GraphQLFeed { public DataFetcher feedId(); - public DataFetcher publisher(); + public DataFetcher publisher(); } /** Feed publisher information */ diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml b/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml index 55f76863cc6..29c2bff0257 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/graphql-codegen.yml @@ -56,6 +56,7 @@ config: elevationProfileComponent: org.opentripplanner.model.plan.ElevationProfile.Step Emissions: org.opentripplanner.model.plan.Emissions#Emissions Feed: String + FeedPublisher: org.opentripplanner.apis.gtfs.model.FeedPublisher#FeedPublisher Geometry: org.locationtech.jts.geom.Geometry#Geometry InputField: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLInputField#GraphQLInputField Itinerary: org.opentripplanner.model.plan.Itinerary#Itinerary From 01e2a14fe45e7f22f40aa2b2690208a1849a61f1 Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Tue, 28 May 2024 12:17:35 +0300 Subject: [PATCH 13/35] Make FeedPublisher nullable --- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 15de75f5408..0ea8899ba32 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -997,7 +997,7 @@ type Feed { agencies: [Agency] """publisher""" - publisher: FeedPublisher! + publisher: FeedPublisher """ Alerts relevant for the feed. From a1818037c4db49fa8d83d656c8d797edf11cd43b Mon Sep 17 00:00:00 2001 From: Vesa Meskanen Date: Tue, 28 May 2024 15:14:25 +0300 Subject: [PATCH 14/35] Update src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls Co-authored-by: Leonard Ehrenfried --- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 0ea8899ba32..41ed352ebf1 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -996,7 +996,7 @@ type Feed { """List of agencies which provide data to this feed""" agencies: [Agency] - """publisher""" + "The publisher of the input transit data." publisher: FeedPublisher """ From d3a9d9721494f149ed99a4f285a4691dd06d24fb Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 28 May 2024 15:11:33 +0200 Subject: [PATCH 15/35] Remove long-disabled MMRI tests --- .../mmri/AllModesAndAgenciesTest.java | 31 ---------- .../mmri/ExcludedStopsTest.java | 29 ---------- .../org/opentripplanner/mmri/OnTripTest.java | 41 ------------- .../mmri/PlannerstackScenarioTest.java | 48 ---------------- .../opentripplanner/mmri/PreferencesTest.java | 26 --------- .../mmri/ServiceAlertTest.java | 29 ---------- .../org/opentripplanner/mmri/TimeTest.java | 25 -------- .../mmri/TransferTimeTest.java | 54 ------------------ src/test/resources/mmri/1a/agency.txt | 2 - src/test/resources/mmri/1a/calendar_dates.txt | 4 -- src/test/resources/mmri/1a/routes.txt | 4 -- src/test/resources/mmri/1a/stop_times.txt | 7 --- src/test/resources/mmri/1a/stops.txt | 7 --- src/test/resources/mmri/1a/transfers.txt | 3 - src/test/resources/mmri/1a/trips.txt | 4 -- src/test/resources/mmri/2a2/agency.txt | 2 - .../resources/mmri/2a2/calendar_dates.txt | 2 - src/test/resources/mmri/2a2/routes.txt | 3 - src/test/resources/mmri/2a2/stop_times.txt | 15 ----- src/test/resources/mmri/2a2/stops.txt | 5 -- src/test/resources/mmri/2a2/transfers.txt | 2 - src/test/resources/mmri/2a2/trips.txt | 8 --- src/test/resources/mmri/2f/agency.txt | 2 - src/test/resources/mmri/2f/calendar_dates.txt | 2 - src/test/resources/mmri/2f/routes.txt | 4 -- src/test/resources/mmri/2f/stop_times.txt | 9 --- src/test/resources/mmri/2f/stops.txt | 4 -- src/test/resources/mmri/2f/trips.txt | 4 -- src/test/resources/mmri/3f/agency.txt | 2 - src/test/resources/mmri/3f/calendar_dates.txt | 2 - src/test/resources/mmri/3f/routes.txt | 3 - src/test/resources/mmri/3f/stop_times.txt | 7 --- src/test/resources/mmri/3f/stops.txt | 5 -- src/test/resources/mmri/3f/trips.txt | 3 - src/test/resources/mmri/3i.pb | Bin 51 -> 0 bytes src/test/resources/mmri/3i/agency.txt | 2 - src/test/resources/mmri/3i/calendar_dates.txt | 2 - src/test/resources/mmri/3i/routes.txt | 2 - src/test/resources/mmri/3i/stop_times.txt | 3 - src/test/resources/mmri/3i/stops.txt | 3 - src/test/resources/mmri/3i/trips.txt | 2 - .../resources/mmri/plannerstack_scenario.pb | Bin 120 -> 0 bytes .../mmri/plannerstack_scenario/agency.txt | 2 - .../plannerstack_scenario/calendar_dates.txt | 2 - .../mmri/plannerstack_scenario/routes.txt | 4 -- .../mmri/plannerstack_scenario/stop_times.txt | 12 ---- .../mmri/plannerstack_scenario/stops.txt | 4 -- .../mmri/plannerstack_scenario/trips.txt | 5 -- 48 files changed, 441 deletions(-) delete mode 100644 src/test/java/org/opentripplanner/mmri/AllModesAndAgenciesTest.java delete mode 100644 src/test/java/org/opentripplanner/mmri/ExcludedStopsTest.java delete mode 100644 src/test/java/org/opentripplanner/mmri/OnTripTest.java delete mode 100644 src/test/java/org/opentripplanner/mmri/PlannerstackScenarioTest.java delete mode 100644 src/test/java/org/opentripplanner/mmri/ServiceAlertTest.java delete mode 100644 src/test/java/org/opentripplanner/mmri/TransferTimeTest.java delete mode 100644 src/test/resources/mmri/1a/agency.txt delete mode 100644 src/test/resources/mmri/1a/calendar_dates.txt delete mode 100644 src/test/resources/mmri/1a/routes.txt delete mode 100644 src/test/resources/mmri/1a/stop_times.txt delete mode 100644 src/test/resources/mmri/1a/stops.txt delete mode 100644 src/test/resources/mmri/1a/transfers.txt delete mode 100644 src/test/resources/mmri/1a/trips.txt delete mode 100644 src/test/resources/mmri/2a2/agency.txt delete mode 100644 src/test/resources/mmri/2a2/calendar_dates.txt delete mode 100644 src/test/resources/mmri/2a2/routes.txt delete mode 100644 src/test/resources/mmri/2a2/stop_times.txt delete mode 100644 src/test/resources/mmri/2a2/stops.txt delete mode 100644 src/test/resources/mmri/2a2/transfers.txt delete mode 100644 src/test/resources/mmri/2a2/trips.txt delete mode 100644 src/test/resources/mmri/2f/agency.txt delete mode 100644 src/test/resources/mmri/2f/calendar_dates.txt delete mode 100644 src/test/resources/mmri/2f/routes.txt delete mode 100644 src/test/resources/mmri/2f/stop_times.txt delete mode 100644 src/test/resources/mmri/2f/stops.txt delete mode 100644 src/test/resources/mmri/2f/trips.txt delete mode 100644 src/test/resources/mmri/3f/agency.txt delete mode 100644 src/test/resources/mmri/3f/calendar_dates.txt delete mode 100644 src/test/resources/mmri/3f/routes.txt delete mode 100644 src/test/resources/mmri/3f/stop_times.txt delete mode 100644 src/test/resources/mmri/3f/stops.txt delete mode 100644 src/test/resources/mmri/3f/trips.txt delete mode 100644 src/test/resources/mmri/3i.pb delete mode 100644 src/test/resources/mmri/3i/agency.txt delete mode 100644 src/test/resources/mmri/3i/calendar_dates.txt delete mode 100644 src/test/resources/mmri/3i/routes.txt delete mode 100644 src/test/resources/mmri/3i/stop_times.txt delete mode 100644 src/test/resources/mmri/3i/stops.txt delete mode 100644 src/test/resources/mmri/3i/trips.txt delete mode 100644 src/test/resources/mmri/plannerstack_scenario.pb delete mode 100644 src/test/resources/mmri/plannerstack_scenario/agency.txt delete mode 100644 src/test/resources/mmri/plannerstack_scenario/calendar_dates.txt delete mode 100644 src/test/resources/mmri/plannerstack_scenario/routes.txt delete mode 100644 src/test/resources/mmri/plannerstack_scenario/stop_times.txt delete mode 100644 src/test/resources/mmri/plannerstack_scenario/stops.txt delete mode 100644 src/test/resources/mmri/plannerstack_scenario/trips.txt diff --git a/src/test/java/org/opentripplanner/mmri/AllModesAndAgenciesTest.java b/src/test/java/org/opentripplanner/mmri/AllModesAndAgenciesTest.java deleted file mode 100644 index f4e0a42fe83..00000000000 --- a/src/test/java/org/opentripplanner/mmri/AllModesAndAgenciesTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.opentripplanner.mmri; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.opentripplanner.GtfsTest; -import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.model.plan.Leg; - -@Disabled("Requires stop-to-stop transfers without street network") -public class AllModesAndAgenciesTest extends GtfsTest { - - @Override - public final String getFeedName() { - return "mmri/1a"; - } - - @Test - public void test1a1() { - Itinerary itinerary = plan(+1388530800L, "1a1", "1a6", null, false, false, null, "", "", 5); - - Leg[] legs = itinerary.getLegs().toArray(new Leg[5]); - - validateLeg(legs[0], 1388530860000L, 1388530920000L, "1a2", "1a1", null); - validateLeg(legs[2], 1388530980000L, 1388531040000L, "1a4", "1a3", null); - validateLeg(legs[4], 1388531100000L, 1388531160000L, "1a6", "1a5", null); - - assertEquals("", itinerary.toStr()); - } -} diff --git a/src/test/java/org/opentripplanner/mmri/ExcludedStopsTest.java b/src/test/java/org/opentripplanner/mmri/ExcludedStopsTest.java deleted file mode 100644 index 4fe48f2c123..00000000000 --- a/src/test/java/org/opentripplanner/mmri/ExcludedStopsTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.opentripplanner.mmri; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.opentripplanner.GtfsTest; -import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.model.plan.Leg; - -@Disabled("Requires stop banning") -public class ExcludedStopsTest extends GtfsTest { - - @Override - public final String getFeedName() { - return "mmri/3f"; - } - - @Test - public void test3f1() { - Itinerary itinerary = plan(+1388530860L, "3f1", "3f3", null, false, false, null, "", "3f2", 1); - - Leg leg = itinerary.getLegs().toArray(new Leg[1])[0]; - - validateLeg(leg, 1388530860000L, 1388531040000L, "3f3", "3f1", null); - - assertEquals("", itinerary.toStr()); - } -} diff --git a/src/test/java/org/opentripplanner/mmri/OnTripTest.java b/src/test/java/org/opentripplanner/mmri/OnTripTest.java deleted file mode 100644 index 2b0e574f352..00000000000 --- a/src/test/java/org/opentripplanner/mmri/OnTripTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.opentripplanner.mmri; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.opentripplanner.GtfsTest; -import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.model.plan.Leg; - -@Disabled("Requires departing onboard trip") -public class OnTripTest extends GtfsTest { - - @Override - public final String getFeedName() { - return "mmri/2f"; - } - - @Test - public void test2f1() { - Itinerary itinerary = plan( - +1388530920L, - null, - "2f2", - "2f|intercity", - false, - false, - null, - "", - "", - 2 - ); - - Leg[] legs = itinerary.getLegs().toArray(new Leg[2]); - - validateLeg(legs[0], 1388530920000L, 1388531040000L, "2f3", null, null); - validateLeg(legs[1], 1388531160000L, 1388531340000L, "2f2", "2f3", null); - - assertEquals("", itinerary.toStr()); - } -} diff --git a/src/test/java/org/opentripplanner/mmri/PlannerstackScenarioTest.java b/src/test/java/org/opentripplanner/mmri/PlannerstackScenarioTest.java deleted file mode 100644 index 1e0ac9b96f2..00000000000 --- a/src/test/java/org/opentripplanner/mmri/PlannerstackScenarioTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.opentripplanner.mmri; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.opentripplanner.GtfsTest; -import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.model.plan.Leg; - -@Disabled("Requires departing onboard a trip") -public class PlannerstackScenarioTest extends GtfsTest { - - @Override - public final String getFeedName() { - return "mmri/plannerstack_scenario"; - } - - @Test - public void testPlannerstackScenario() { - Itinerary itinerary = plan( - +1388531220L, - null, - "plannerstack_scenario2", - "plannerstack_scenario|intercity", - false, - false, - null, - "", - "", - 2 - ); - - Leg[] legs = itinerary.getLegs().toArray(new Leg[2]); - - validateLeg(legs[0], 1388531220000L, 1388531340000L, "plannerstack_scenario3", null, null); - validateLeg( - legs[1], - 1388531400000L, - 1388531640000L, - "plannerstack_scenario2", - "plannerstack_scenario3", - null - ); - - assertEquals("", itinerary.toStr()); - } -} diff --git a/src/test/java/org/opentripplanner/mmri/PreferencesTest.java b/src/test/java/org/opentripplanner/mmri/PreferencesTest.java index d3c55097511..c33f67345fc 100644 --- a/src/test/java/org/opentripplanner/mmri/PreferencesTest.java +++ b/src/test/java/org/opentripplanner/mmri/PreferencesTest.java @@ -1,9 +1,7 @@ package org.opentripplanner.mmri; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.transit.model.basic.TransitMode.BUS; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.opentripplanner.GtfsTest; import org.opentripplanner.model.plan.Itinerary; @@ -30,28 +28,4 @@ public void test2c1() { itinerary.toStr() ); } - - @Test - @Disabled - public void test2c2() { - Itinerary itinerary = plan(+1388530860L, "2c1", "2c3", null, false, false, BUS, "", "", 3); - - Leg[] legs = itinerary.getLegs().toArray(new Leg[3]); - - validateLeg(legs[1], 1388530920000L, 1388531160000L, "2c5", "2c4", null); - - assertEquals("", itinerary.toStr()); - } - - @Test - @Disabled - public void test2c3() { - Itinerary itinerary = plan(+1388530860L, "2c1", "2c3", null, false, true, null, "", "", 3); - - Leg[] legs = itinerary.getLegs().toArray(new Leg[3]); - - validateLeg(legs[1], 1388530920000L, 1388531160000L, "2c5", "2c4", null); - - assertEquals("", itinerary.toStr()); - } } diff --git a/src/test/java/org/opentripplanner/mmri/ServiceAlertTest.java b/src/test/java/org/opentripplanner/mmri/ServiceAlertTest.java deleted file mode 100644 index 2d35f0a246d..00000000000 --- a/src/test/java/org/opentripplanner/mmri/ServiceAlertTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.opentripplanner.mmri; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.opentripplanner.GtfsTest; -import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.model.plan.Leg; - -@Disabled("Service alerts not mapped correctly") -public class ServiceAlertTest extends GtfsTest { - - @Override - public final String getFeedName() { - return "mmri/3i"; - } - - @Test - public void test3i1() { - Itinerary itinerary = plan(+1388530860L, "3i1", "3i2", null, false, false, null, "", "", 1); - - Leg leg = itinerary.getLegs().toArray(new Leg[1])[0]; - - validateLeg(leg, 1388530860000L, 1388530920000L, "3i2", "3i1", "Unknown effect"); - - assertEquals("", itinerary.toStr()); - } -} diff --git a/src/test/java/org/opentripplanner/mmri/TimeTest.java b/src/test/java/org/opentripplanner/mmri/TimeTest.java index 77123d3e656..90be00a56bb 100644 --- a/src/test/java/org/opentripplanner/mmri/TimeTest.java +++ b/src/test/java/org/opentripplanner/mmri/TimeTest.java @@ -2,7 +2,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.opentripplanner.GtfsTest; import org.opentripplanner.model.plan.Itinerary; @@ -37,30 +36,6 @@ public void test1g2() { assertEquals("Stop 1g1 ~ BUS bus 0:01 0:02 ~ Stop 1g2 [C₁90]", itinerary.toStr()); } - @Test - @Disabled - public void test1g3() { - Itinerary itinerary = plan(+1388617380L, "1g1", "1g2", null, false, false, null, "", "", 1); - - Leg leg = itinerary.getLegs().toArray(new Leg[1])[0]; - - validateLeg(leg, 1388703660000L, 1388703720000L, "1g2", "1g1", null); - - assertEquals("", itinerary.toStr()); - } - - @Test - @Disabled - public void test1g4() { - Itinerary itinerary = plan(-1388617440L, "1g1", "1g2", null, false, false, null, "", "", 1); - - Leg leg = itinerary.getLegs().toArray(new Leg[1])[0]; - - validateLeg(leg, 1388531100000L, 1388531160000L, "1g2", "1g1", null); - - assertEquals("", itinerary.toStr()); - } - @Test public void test1g5() { Itinerary itinerary = plan(+1388703780L, "1g1", "1g2", null, false, false, null, "", "", 1); diff --git a/src/test/java/org/opentripplanner/mmri/TransferTimeTest.java b/src/test/java/org/opentripplanner/mmri/TransferTimeTest.java deleted file mode 100644 index 9b0fc12cf37..00000000000 --- a/src/test/java/org/opentripplanner/mmri/TransferTimeTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.opentripplanner.mmri; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.opentripplanner.GtfsTest; -import org.opentripplanner.model.plan.Itinerary; -import org.opentripplanner.model.plan.Leg; - -@Disabled -public class TransferTimeTest extends GtfsTest { - - @Override - public final String getFeedName() { - return "mmri/2a2"; - } - - @Test - public void test2a3() { - Itinerary itinerary = plan(+1388530860L, "2a3", "2a6", null, false, false, null, "", "", 3); - - Leg[] legs = itinerary.getLegs().toArray(new Leg[3]); - - validateLeg(legs[0], 1388530860000L, 1388530920000L, "2a4", "2a3", null); - validateLeg(legs[2], 1388531280000L, 1388531340000L, "2a6", "2a5", null); - - assertEquals("", itinerary.toStr()); - } - - @Test - public void test2a4() { - Itinerary itinerary = plan(+1388530920L, "2a3", "2a6", null, false, false, null, "", "", 3); - - Leg[] legs = itinerary.getLegs().toArray(new Leg[3]); - - validateLeg(legs[0], 1388531040000L, 1388531100000L, "2a4", "2a3", null); - validateLeg(legs[2], 1388531400000L, 1388531460000L, "2a6", "2a5", null); - - assertEquals("", itinerary.toStr()); - } - - @Test - public void test2a5() { - Itinerary itinerary = plan(-1388531460L, "2a3", "2a6", null, false, false, null, "", "", 3); - - Leg[] legs = itinerary.getLegs().toArray(new Leg[3]); - - validateLeg(legs[0], 1388531040000L, 1388531100000L, "2a4", "2a3", null); - validateLeg(legs[2], 1388531400000L, 1388531460000L, "2a6", "2a5", null); - - assertEquals("", itinerary.toStr()); - } -} diff --git a/src/test/resources/mmri/1a/agency.txt b/src/test/resources/mmri/1a/agency.txt deleted file mode 100644 index d6f92d6af7f..00000000000 --- a/src/test/resources/mmri/1a/agency.txt +++ /dev/null @@ -1,2 +0,0 @@ -agency_id,agency_name,agency_url,agency_timezone,agency_lang -MMRI,Multimodale Reisinformatie,http://mmri.nl/,Europe/Amsterdam,nl diff --git a/src/test/resources/mmri/1a/calendar_dates.txt b/src/test/resources/mmri/1a/calendar_dates.txt deleted file mode 100644 index bc0abe90518..00000000000 --- a/src/test/resources/mmri/1a/calendar_dates.txt +++ /dev/null @@ -1,4 +0,0 @@ -date,service_id,exception_type -20140101,1a|bus|1,1 -20140101,1a|ferry|1,1 -20140101,1a|train|1,1 diff --git a/src/test/resources/mmri/1a/routes.txt b/src/test/resources/mmri/1a/routes.txt deleted file mode 100644 index 130126398bf..00000000000 --- a/src/test/resources/mmri/1a/routes.txt +++ /dev/null @@ -1,4 +0,0 @@ -agency_id,route_id,route_short_name,route_long_name,route_type -MMRI,1a|bus,bus,,3 -MMRI,1a|ferry,ferry,,4 -MMRI,1a|train,train,,2 diff --git a/src/test/resources/mmri/1a/stop_times.txt b/src/test/resources/mmri/1a/stop_times.txt deleted file mode 100644 index 280a530103d..00000000000 --- a/src/test/resources/mmri/1a/stop_times.txt +++ /dev/null @@ -1,7 +0,0 @@ -trip_id,arrival_time,departure_time,stop_id,stop_sequence -1a|bus|1,00:01:00,00:01:00,1a1,1 -1a|bus|1,00:02:00,00:02:00,1a2,2 -1a|ferry|1,00:03:00,00:03:00,1a3,3 -1a|ferry|1,00:04:00,00:04:00,1a4,4 -1a|train|1,00:05:00,00:05:00,1a5,5 -1a|train|1,00:06:00,00:06:00,1a6,6 diff --git a/src/test/resources/mmri/1a/stops.txt b/src/test/resources/mmri/1a/stops.txt deleted file mode 100644 index 11b92589dd2..00000000000 --- a/src/test/resources/mmri/1a/stops.txt +++ /dev/null @@ -1,7 +0,0 @@ -stop_id,stop_name,stop_lat,stop_lon -1a1,Stop 1a1,1.101,1.1 -1a2,Stop 1a2,1.102,1.1 -1a3,Stop 1a3,1.103,1.1 -1a4,Stop 1a4,1.104,1.1 -1a5,Stop 1a5,1.105,1.1 -1a6,Stop 1a6,1.106,1.1 diff --git a/src/test/resources/mmri/1a/transfers.txt b/src/test/resources/mmri/1a/transfers.txt deleted file mode 100644 index 9bdfd232de9..00000000000 --- a/src/test/resources/mmri/1a/transfers.txt +++ /dev/null @@ -1,3 +0,0 @@ -from_stop_id,to_stop_id,transfer_type,min_transfer_time -1a2,1a3,2,0 -1a4,1a5,2,0 diff --git a/src/test/resources/mmri/1a/trips.txt b/src/test/resources/mmri/1a/trips.txt deleted file mode 100644 index 4573658c9a5..00000000000 --- a/src/test/resources/mmri/1a/trips.txt +++ /dev/null @@ -1,4 +0,0 @@ -route_id,service_id,trip_id -1a|bus,1a|bus|1,1a|bus|1 -1a|ferry,1a|ferry|1,1a|ferry|1 -1a|train,1a|train|1,1a|train|1 diff --git a/src/test/resources/mmri/2a2/agency.txt b/src/test/resources/mmri/2a2/agency.txt deleted file mode 100644 index d6f92d6af7f..00000000000 --- a/src/test/resources/mmri/2a2/agency.txt +++ /dev/null @@ -1,2 +0,0 @@ -agency_id,agency_name,agency_url,agency_timezone,agency_lang -MMRI,Multimodale Reisinformatie,http://mmri.nl/,Europe/Amsterdam,nl diff --git a/src/test/resources/mmri/2a2/calendar_dates.txt b/src/test/resources/mmri/2a2/calendar_dates.txt deleted file mode 100644 index 2461c7fe35f..00000000000 --- a/src/test/resources/mmri/2a2/calendar_dates.txt +++ /dev/null @@ -1,2 +0,0 @@ -date,service_id,exception_type -20140101,ignore,1 diff --git a/src/test/resources/mmri/2a2/routes.txt b/src/test/resources/mmri/2a2/routes.txt deleted file mode 100644 index f8da6695081..00000000000 --- a/src/test/resources/mmri/2a2/routes.txt +++ /dev/null @@ -1,3 +0,0 @@ -agency_id,route_id,route_short_name,route_long_name,route_type -MMRI,2a2|bus|1,bus 1,,3 -MMRI,2a2|bus|2,bus 2,,3 diff --git a/src/test/resources/mmri/2a2/stop_times.txt b/src/test/resources/mmri/2a2/stop_times.txt deleted file mode 100644 index a3bb8933370..00000000000 --- a/src/test/resources/mmri/2a2/stop_times.txt +++ /dev/null @@ -1,15 +0,0 @@ -trip_id,arrival_time,departure_time,stop_id,stop_sequence -2a2|bus|1|1,00:01:00,00:01:00,2a3,1 -2a2|bus|1|1,00:02:00,00:02:00,2a4,2 -2a2|bus|1|2,00:04:00,00:04:00,2a3,1 -2a2|bus|1|2,00:05:00,00:05:00,2a4,2 -2a2|bus|1|3,00:07:00,00:07:00,2a3,1 -2a2|bus|1|3,00:08:00,00:08:00,2a4,2 -2a2|bus|2|1,00:02:00,00:02:00,2a5,1 -2a2|bus|2|1,00:03:00,00:03:00,2a6,2 -2a2|bus|2|2,00:05:00,00:05:00,2a5,1 -2a2|bus|2|2,00:06:00,00:06:00,2a6,2 -2a2|bus|2|3,00:08:00,00:08:00,2a5,1 -2a2|bus|2|3,00:09:00,00:09:00,2a6,2 -2a2|bus|2|4,00:10:00,00:10:00,2a5,1 -2a2|bus|2|4,00:11:00,00:11:00,2a6,2 \ No newline at end of file diff --git a/src/test/resources/mmri/2a2/stops.txt b/src/test/resources/mmri/2a2/stops.txt deleted file mode 100644 index c3c457bc753..00000000000 --- a/src/test/resources/mmri/2a2/stops.txt +++ /dev/null @@ -1,5 +0,0 @@ -stop_id,stop_name,stop_lat,stop_lon -2a3,Stop 2a3,2.103,2.102 -2a4,Stop 2a4,2.104,2.102 -2a5,Stop 2a5,2.105,2.102 -2a6,Stop 2a6,2.106,2.102 diff --git a/src/test/resources/mmri/2a2/transfers.txt b/src/test/resources/mmri/2a2/transfers.txt deleted file mode 100644 index 4ec2f4adf41..00000000000 --- a/src/test/resources/mmri/2a2/transfers.txt +++ /dev/null @@ -1,2 +0,0 @@ -from_stop_id,to_stop_id,transfer_type,min_transfer_time -2a4,2a5,2,300 diff --git a/src/test/resources/mmri/2a2/trips.txt b/src/test/resources/mmri/2a2/trips.txt deleted file mode 100644 index 1a8f2a56fdc..00000000000 --- a/src/test/resources/mmri/2a2/trips.txt +++ /dev/null @@ -1,8 +0,0 @@ -route_id,service_id,trip_id -2a2|bus|1,ignore,2a2|bus|1|1 -2a2|bus|1,ignore,2a2|bus|1|2 -2a2|bus|1,ignore,2a2|bus|1|3 -2a2|bus|2,ignore,2a2|bus|2|1 -2a2|bus|2,ignore,2a2|bus|2|2 -2a2|bus|2,ignore,2a2|bus|2|3 -2a2|bus|2,ignore,2a2|bus|2|4 \ No newline at end of file diff --git a/src/test/resources/mmri/2f/agency.txt b/src/test/resources/mmri/2f/agency.txt deleted file mode 100644 index d6f92d6af7f..00000000000 --- a/src/test/resources/mmri/2f/agency.txt +++ /dev/null @@ -1,2 +0,0 @@ -agency_id,agency_name,agency_url,agency_timezone,agency_lang -MMRI,Multimodale Reisinformatie,http://mmri.nl/,Europe/Amsterdam,nl diff --git a/src/test/resources/mmri/2f/calendar_dates.txt b/src/test/resources/mmri/2f/calendar_dates.txt deleted file mode 100644 index 2461c7fe35f..00000000000 --- a/src/test/resources/mmri/2f/calendar_dates.txt +++ /dev/null @@ -1,2 +0,0 @@ -date,service_id,exception_type -20140101,ignore,1 diff --git a/src/test/resources/mmri/2f/routes.txt b/src/test/resources/mmri/2f/routes.txt deleted file mode 100644 index 5875e0081d4..00000000000 --- a/src/test/resources/mmri/2f/routes.txt +++ /dev/null @@ -1,4 +0,0 @@ -agency_id,route_id,route_short_name,route_long_name,route_type -MMRI,2f|intercity,,Intercity,2 -MMRI,2f|slt|1,,Local train 1,2 -MMRI,2f|slt|2,,Local train 2,2 diff --git a/src/test/resources/mmri/2f/stop_times.txt b/src/test/resources/mmri/2f/stop_times.txt deleted file mode 100644 index 559d84d992f..00000000000 --- a/src/test/resources/mmri/2f/stop_times.txt +++ /dev/null @@ -1,9 +0,0 @@ -trip_id,arrival_time,departure_time,stop_id,stop_sequence -2f|intercity,00:01:00,00:01:00,2f1,1 -2f|intercity,00:04:00,00:04:00,2f3,2 -2f|slt|1,00:01:00,00:01:00,2f1,1 -2f|slt|1,00:03:00,00:03:00,2f2,2 -2f|slt|1,00:05:00,00:05:00,2f3,3 -2f|slt|2,00:06:00,00:06:00,2f3,1 -2f|slt|2,00:09:00,00:09:00,2f2,2 -2f|slt|2,00:11:00,00:11:00,2f1,3 diff --git a/src/test/resources/mmri/2f/stops.txt b/src/test/resources/mmri/2f/stops.txt deleted file mode 100644 index 538a3240e55..00000000000 --- a/src/test/resources/mmri/2f/stops.txt +++ /dev/null @@ -1,4 +0,0 @@ -stop_id,stop_name,stop_lat,stop_lon -2f1,Stop 2f1,2.701,2.700 -2f2,Stop 2f2,2.702,2.700 -2f3,Stop 2f3,2.703,2.700 diff --git a/src/test/resources/mmri/2f/trips.txt b/src/test/resources/mmri/2f/trips.txt deleted file mode 100644 index f9dba48f134..00000000000 --- a/src/test/resources/mmri/2f/trips.txt +++ /dev/null @@ -1,4 +0,0 @@ -route_id,service_id,trip_id -2f|intercity,ignore,2f|intercity -2f|slt|1,ignore,2f|slt|1 -2f|slt|2,ignore,2f|slt|2 diff --git a/src/test/resources/mmri/3f/agency.txt b/src/test/resources/mmri/3f/agency.txt deleted file mode 100644 index d6f92d6af7f..00000000000 --- a/src/test/resources/mmri/3f/agency.txt +++ /dev/null @@ -1,2 +0,0 @@ -agency_id,agency_name,agency_url,agency_timezone,agency_lang -MMRI,Multimodale Reisinformatie,http://mmri.nl/,Europe/Amsterdam,nl diff --git a/src/test/resources/mmri/3f/calendar_dates.txt b/src/test/resources/mmri/3f/calendar_dates.txt deleted file mode 100644 index 2461c7fe35f..00000000000 --- a/src/test/resources/mmri/3f/calendar_dates.txt +++ /dev/null @@ -1,2 +0,0 @@ -date,service_id,exception_type -20140101,ignore,1 diff --git a/src/test/resources/mmri/3f/routes.txt b/src/test/resources/mmri/3f/routes.txt deleted file mode 100644 index 33917fc7217..00000000000 --- a/src/test/resources/mmri/3f/routes.txt +++ /dev/null @@ -1,3 +0,0 @@ -agency_id,route_id,route_short_name,route_long_name,route_type -MMRI,3f|1,,Intercity 1,2 -MMRI,3f|2,,Intercity 2,2 diff --git a/src/test/resources/mmri/3f/stop_times.txt b/src/test/resources/mmri/3f/stop_times.txt deleted file mode 100644 index 563936db238..00000000000 --- a/src/test/resources/mmri/3f/stop_times.txt +++ /dev/null @@ -1,7 +0,0 @@ -trip_id,arrival_time,departure_time,stop_id,stop_sequence -3f|1,00:01:00,00:01:00,3f1,1 -3f|1,00:02:00,00:02:00,3f2,2 -3f|1,00:03:00,00:03:00,3f3,3 -3f|2,00:01:00,00:01:00,3f1,1 -3f|2,00:02:00,00:02:00,3f4,2 -3f|2,00:04:00,00:04:00,3f3,3 diff --git a/src/test/resources/mmri/3f/stops.txt b/src/test/resources/mmri/3f/stops.txt deleted file mode 100644 index 7ccbea9059f..00000000000 --- a/src/test/resources/mmri/3f/stops.txt +++ /dev/null @@ -1,5 +0,0 @@ -stop_id,stop_name,stop_lat,stop_lon -3f1,Stop 3f1,3.601,3.602 -3f2,Stop 3f2,3.602,3.601 -3f3,Stop 3f3,3.603,3.602 -3f4,Stop 3f4,3.602,3.603 diff --git a/src/test/resources/mmri/3f/trips.txt b/src/test/resources/mmri/3f/trips.txt deleted file mode 100644 index c16ec0732bb..00000000000 --- a/src/test/resources/mmri/3f/trips.txt +++ /dev/null @@ -1,3 +0,0 @@ -route_id,service_id,trip_id -3f|1,ignore,3f|1 -3f|2,ignore,3f|2 diff --git a/src/test/resources/mmri/3i.pb b/src/test/resources/mmri/3i.pb deleted file mode 100644 index f03fd3dc6bff1eaaf69b7a3a966c5243e0a854e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51 zcmd<$ Date: Wed, 22 May 2024 11:29:52 +0200 Subject: [PATCH 16/35] Introduce primary and secondary elements for stop clusters --- .../ext/geocoder/LuceneIndexTest.java | 26 ++++++++++------- .../ext/geocoder/LuceneIndex.java | 5 +++- .../ext/geocoder/StopCluster.java | 28 ++++++++++++++----- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index b1fb33dfdd3..15f205ad802 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -10,7 +10,9 @@ import java.time.LocalDate; import java.util.List; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; +import javax.annotation.Nonnull; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -213,13 +215,13 @@ class StopClusters { ) void stopClustersWithTypos(String searchTerm) { var results = index.queryStopClusters(searchTerm).toList(); - var ids = results.stream().map(StopCluster::id).toList(); + var ids = results.stream().map(primaryId()).toList(); assertEquals(List.of(ALEXANDERPLATZ_STATION.getId()), ids); } @Test void fuzzyStopClusters() { - var result1 = index.queryStopClusters("arts").map(StopCluster::id).toList(); + var result1 = index.queryStopClusters("arts").map(primaryId()).toList(); assertEquals(List.of(ARTS_CENTER.getId()), result1); } @@ -227,7 +229,7 @@ void fuzzyStopClusters() { void deduplicatedStopClusters() { var result = index.queryStopClusters("lich").toList(); assertEquals(1, result.size()); - assertEquals(LICHTERFELDE_OST_1.getName().toString(), result.getFirst().name()); + assertEquals(LICHTERFELDE_OST_1.getName().toString(), result.getFirst().primary().name()); } @ParameterizedTest @@ -259,7 +261,7 @@ void deduplicatedStopClusters() { } ) void stopClustersWithSpace(String query) { - var result = index.queryStopClusters(query).map(StopCluster::id).toList(); + var result = index.queryStopClusters(query).map(primaryId()).toList(); assertEquals(List.of(FIVE_POINTS_STATION.getId()), result); } @@ -268,7 +270,7 @@ void stopClustersWithSpace(String query) { void fuzzyStopCode(String query) { var result = index.queryStopClusters(query).toList(); assertEquals(1, result.size()); - assertEquals(ARTS_CENTER.getName().toString(), result.getFirst().name()); + assertEquals(ARTS_CENTER.getName().toString(), result.getFirst().primary().name()); } @Test @@ -276,16 +278,20 @@ void modes() { var result = index.queryStopClusters("westh").toList(); assertEquals(1, result.size()); var stop = result.getFirst(); - assertEquals(WESTHAFEN.getName().toString(), stop.name()); - assertEquals(List.of(FERRY.name(), BUS.name()), stop.modes()); + assertEquals(WESTHAFEN.getName().toString(), stop.primary().name()); + assertEquals(List.of(FERRY.name(), BUS.name()), stop.primary().modes()); } @Test void agenciesAndFeedPublisher() { var result = index.queryStopClusters("alexanderplatz").toList().getFirst(); - assertEquals(ALEXANDERPLATZ_STATION.getName().toString(), result.name()); - assertEquals(List.of(StopClusterMapper.toAgency(BVG)), result.agencies()); - assertEquals("A Publisher", result.feedPublisher().name()); + assertEquals(ALEXANDERPLATZ_STATION.getName().toString(), result.primary().name()); + assertEquals(List.of(StopClusterMapper.toAgency(BVG)), result.primary().agencies()); + assertEquals("A Publisher", result.primary().feedPublisher().name()); } } + + private static @Nonnull Function primaryId() { + return c -> c.primary().id(); + } } diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index 56769db0028..b43028ff4d9 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -6,6 +6,7 @@ import java.io.Serializable; import java.util.Arrays; import java.util.Collection; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -198,7 +199,7 @@ private StopCluster toStopCluster(Document document) { var feedPublisher = StopClusterMapper.toFeedPublisher( transitService.getFeedInfo(clusterId.getFeedId()) ); - return new StopCluster( + var primary = new StopCluster.Location( clusterId, code, name, @@ -207,6 +208,8 @@ private StopCluster toStopCluster(Document document) { agencies, feedPublisher ); + + return new StopCluster(primary, List.of()); } static IndexWriterConfig iwcWithSuggestField(Analyzer analyzer, final Set suggestFields) { diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java index 8ffd44511fd..20c86e18ed9 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java @@ -2,6 +2,7 @@ import java.util.Collection; import java.util.List; +import java.util.Objects; import javax.annotation.Nullable; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -15,13 +16,8 @@ * - if stops are closer than 10 meters to each and have an identical name, only one is returned */ record StopCluster( - FeedScopedId id, - @Nullable String code, - String name, - Coordinate coordinate, - Collection modes, - List agencies, - @Nullable FeedPublisher feedPublisher + Location primary, + Collection secondaries ) { /** * Easily serializable version of a coordinate @@ -37,4 +33,22 @@ public record Agency(FeedScopedId id, String name) {} * Easily serializable version of a feed publisher */ public record FeedPublisher(String name) {} + + public record Location( + FeedScopedId id, + @Nullable String code, + String name, + Coordinate coordinate, + Collection modes, + List agencies, + @Nullable FeedPublisher feedPublisher + ){ + public Location{ + Objects.requireNonNull(id); + Objects.requireNonNull(name); + Objects.requireNonNull(coordinate); + Objects.requireNonNull(modes); + Objects.requireNonNull(agencies); + } + } } From 3686f3543d9eed105aa32431b85ff8dfa3ac2a76 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 22 May 2024 12:18:25 +0200 Subject: [PATCH 17/35] Improve mapping of primaries/secondaries --- .../ext/geocoder/LuceneIndex.java | 36 ++++++++++--------- .../ext/geocoder/LuceneStopCluster.java | 15 ++++---- .../ext/geocoder/StopClusterMapper.java | 32 +++++++++-------- .../framework/collection/ListUtils.java | 13 +++++++ 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index b43028ff4d9..8502bb9887a 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -11,7 +11,6 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Stream; -import javax.annotation.Nullable; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.en.EnglishAnalyzer; import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper; @@ -42,6 +41,7 @@ import org.apache.lucene.search.suggest.document.SuggestIndexSearcher; import org.apache.lucene.store.ByteBuffersDirectory; import org.opentripplanner.ext.geocoder.StopCluster.Coordinate; +import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.standalone.api.OtpServerRequestContext; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -96,8 +96,8 @@ public LuceneIndex(TransitService transitService) { directoryWriter, StopLocation.class, stopLocation.getId().toString(), - stopLocation.getName(), - stopLocation.getCode(), + ListUtils.ofNullable(stopLocation.getName()), + ListUtils.ofNullable(stopLocation.getCode()), stopLocation.getCoordinate().latitude(), stopLocation.getCoordinate().longitude(), Set.of(), @@ -112,8 +112,8 @@ public LuceneIndex(TransitService transitService) { directoryWriter, StopLocationsGroup.class, stopLocationsGroup.getId().toString(), - stopLocationsGroup.getName(), - null, + ListUtils.ofNullable(stopLocationsGroup.getName()), + List.of(), stopLocationsGroup.getCoordinate().latitude(), stopLocationsGroup.getCoordinate().longitude(), Set.of(), @@ -130,13 +130,13 @@ public LuceneIndex(TransitService transitService) { addToIndex( directoryWriter, StopCluster.class, - stopCluster.id().toString(), - I18NString.of(stopCluster.name()), - stopCluster.code(), + stopCluster.primaryId(), + stopCluster.names(), + stopCluster.codes(), stopCluster.coordinate().lat(), stopCluster.coordinate().lon(), stopCluster.modes(), - stopCluster.agencyIds() + List.of() ) ); } @@ -233,8 +233,8 @@ private static void addToIndex( IndexWriter writer, Class type, String id, - I18NString name, - @Nullable String code, + Collection names, + Collection codes, double latitude, double longitude, Collection modes, @@ -245,13 +245,15 @@ private static void addToIndex( Document document = new Document(); document.add(new StoredField(ID, id)); document.add(new TextField(TYPE, typeName, Store.YES)); - document.add(new TextField(NAME, Objects.toString(name), Store.YES)); - document.add(new TextField(NAME_NGRAM, Objects.toString(name), Store.YES)); - document.add(new ContextSuggestField(SUGGEST, Objects.toString(name), 1, typeName)); + for(var name: names) { + document.add(new TextField(NAME, Objects.toString(name), Store.YES)); + document.add(new TextField(NAME_NGRAM, Objects.toString(name), Store.YES)); + document.add(new ContextSuggestField(SUGGEST, Objects.toString(name), 1, typeName)); + } document.add(new StoredField(LAT, latitude)); document.add(new StoredField(LON, longitude)); - if (code != null) { + for (var code : codes) { document.add(new TextField(CODE, code, Store.YES)); document.add(new ContextSuggestField(SUGGEST, code, 1, typeName)); } @@ -259,8 +261,8 @@ private static void addToIndex( for (var mode : modes) { document.add(new TextField(MODE, mode, Store.YES)); } - for (var ids : agencyIds) { - document.add(new TextField(AGENCY_IDS, ids, Store.YES)); + for (var aId : agencyIds) { + document.add(new TextField(AGENCY_IDS, aId, Store.YES)); } try { diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java index f58d7aa9af9..5a52ea2a831 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java @@ -1,17 +1,16 @@ package org.opentripplanner.ext.geocoder; import java.util.Collection; -import javax.annotation.Nullable; -import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.framework.i18n.I18NString; /** * A package-private helper type for transporting data before serializing. */ record LuceneStopCluster( - FeedScopedId id, - @Nullable String code, - String name, - StopCluster.Coordinate coordinate, + String primaryId, + Collection secondaryIds, + Collection names, Collection modes, - Collection agencyIds -) {} + Collection codes, + StopCluster.Coordinate coordinate){ +} diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index 6f16d4a0cce..fd808d41bcf 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -3,6 +3,7 @@ import com.google.common.collect.Iterables; import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.Optional; import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; @@ -61,33 +62,34 @@ Iterable generateStopClusters( LuceneStopCluster map(StopLocationsGroup g) { var modes = transitService.getModesOfStopLocationsGroup(g).stream().map(Enum::name).toList(); - var agencies = agenciesForStopLocationsGroup(g) - .stream() - .map(s -> s.getId().toString()) - .toList(); + + var childStops = g.getChildStops(); + var ids = childStops.stream().map(s -> s.getId().toString()).toList(); + var childNames = childStops.stream().map(StopLocation::getName).filter(Objects::nonNull).toList(); + var codes = childStops.stream().map(StopLocation::getCode).filter(Objects::nonNull).toList(); + return new LuceneStopCluster( - g.getId(), - null, - g.getName().toString(), - toCoordinate(g.getCoordinate()), + g.getId().toString(), + ids, + ListUtils.combine(List.of(g.getName()), childNames), + codes, modes, - agencies + toCoordinate(g.getCoordinate()) ); } Optional map(StopLocation sl) { - var agencies = agenciesForStopLocation(sl).stream().map(a -> a.getId().toString()).toList(); return Optional .ofNullable(sl.getName()) .map(name -> { var modes = transitService.getModesOfStopLocation(sl).stream().map(Enum::name).toList(); return new LuceneStopCluster( - sl.getId(), - sl.getCode(), - name.toString(), - toCoordinate(sl.getCoordinate()), + sl.getId().toString(), + List.of(), + List.of(name), modes, - agencies + ListUtils.ofNullable(sl.getCode()), + toCoordinate(sl.getCoordinate()) ); }); } diff --git a/src/main/java/org/opentripplanner/framework/collection/ListUtils.java b/src/main/java/org/opentripplanner/framework/collection/ListUtils.java index 513c0bcc0d3..302df428d12 100644 --- a/src/main/java/org/opentripplanner/framework/collection/ListUtils.java +++ b/src/main/java/org/opentripplanner/framework/collection/ListUtils.java @@ -57,4 +57,17 @@ public static List distinctByKey( return ret; } + + /** + * Take a single nullable variable and return an empty list if it is null. Otherwise + * return a list with one element. + */ + public static List ofNullable(T input) { + if(input == null){ + return List.of(); + } + else { + return List.of(input); + } + } } From 60469d74ada63ae3ddba7b11b692cb3ae7a4ff44 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 22 May 2024 12:41:24 +0200 Subject: [PATCH 18/35] Rework indexing --- .../ext/geocoder/LuceneIndex.java | 73 ++++++++++++------- .../ext/geocoder/LuceneStopCluster.java | 4 +- .../ext/geocoder/StopCluster.java | 9 +-- .../ext/geocoder/StopClusterMapper.java | 10 ++- .../framework/collection/ListUtils.java | 5 +- .../transit/model/site/GroupOfStations.java | 6 ++ .../model/site/StopLocationsGroup.java | 4 + 7 files changed, 71 insertions(+), 40 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index 8502bb9887a..c39d18d6c22 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -65,10 +65,11 @@ public class LuceneIndex implements Serializable { private final TransitService transitService; private final Analyzer analyzer; private final SuggestIndexSearcher searcher; + private final StopClusterMapper stopClusterMapper; public LuceneIndex(TransitService transitService) { this.transitService = transitService; - StopClusterMapper stopClusterMapper = new StopClusterMapper(transitService); + this.stopClusterMapper = new StopClusterMapper(transitService); this.analyzer = new PerFieldAnalyzerWrapper( @@ -184,34 +185,54 @@ public Stream queryStopClusters(String query) { } private StopCluster toStopCluster(Document document) { - var clusterId = FeedScopedId.parse(document.get(ID)); - var name = document.get(NAME); - var code = document.get(CODE); - var lat = document.getField(LAT).numericValue().doubleValue(); - var lon = document.getField(LON).numericValue().doubleValue(); - var modes = Arrays.asList(document.getValues(MODE)); - var agencies = Arrays - .stream(document.getValues(AGENCY_IDS)) - .map(id -> transitService.getAgencyForId(FeedScopedId.parse(id))) - .filter(Objects::nonNull) - .map(StopClusterMapper::toAgency) - .toList(); - var feedPublisher = StopClusterMapper.toFeedPublisher( - transitService.getFeedInfo(clusterId.getFeedId()) - ); - var primary = new StopCluster.Location( - clusterId, - code, - name, - new Coordinate(lat, lon), - modes, - agencies, - feedPublisher - ); + var primaryId = FeedScopedId.parse(document.get(ID)); + var primary = toLocation(primaryId); return new StopCluster(primary, List.of()); } + private StopCluster.Location toLocation(FeedScopedId id) { + var loc = transitService.getStopLocation(id); + if (loc != null) { + var feedPublisher = StopClusterMapper.toFeedPublisher( + transitService.getFeedInfo(id.getFeedId()) + ); + var agencies = stopClusterMapper + .agenciesForStopLocation(loc) + .stream() + .map(StopClusterMapper::toAgency) + .toList(); + return new StopCluster.Location( + loc.getId(), + loc.getCode(), + loc.getName().toString(), + new Coordinate(loc.getLat(), loc.getLon()), + List.of(), + agencies, + feedPublisher + ); + } else { + var group = transitService.getStopLocationsGroup(id); + var feedPublisher = StopClusterMapper.toFeedPublisher( + transitService.getFeedInfo(id.getFeedId()) + ); + var agencies = stopClusterMapper + .agenciesForStopLocationsGroup(group) + .stream() + .map(StopClusterMapper::toAgency) + .toList(); + return new StopCluster.Location( + group.getId(), + group.getCode(), + group.getName().toString(), + new Coordinate(group.getLat(), group.getLon()), + List.of(), + agencies, + feedPublisher + ); + } + } + static IndexWriterConfig iwcWithSuggestField(Analyzer analyzer, final Set suggestFields) { IndexWriterConfig iwc = new IndexWriterConfig(analyzer); Codec filterCodec = new Lucene99Codec() { @@ -245,7 +266,7 @@ private static void addToIndex( Document document = new Document(); document.add(new StoredField(ID, id)); document.add(new TextField(TYPE, typeName, Store.YES)); - for(var name: names) { + for (var name : names) { document.add(new TextField(NAME, Objects.toString(name), Store.YES)); document.add(new TextField(NAME_NGRAM, Objects.toString(name), Store.YES)); document.add(new ContextSuggestField(SUGGEST, Objects.toString(name), 1, typeName)); diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java index 5a52ea2a831..9ed1b71da76 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java @@ -12,5 +12,5 @@ record LuceneStopCluster( Collection names, Collection modes, Collection codes, - StopCluster.Coordinate coordinate){ -} + StopCluster.Coordinate coordinate +) {} diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java index 20c86e18ed9..4c51c7586dd 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java @@ -15,10 +15,7 @@ * - if a stop has a parent station only the parent is returned * - if stops are closer than 10 meters to each and have an identical name, only one is returned */ -record StopCluster( - Location primary, - Collection secondaries -) { +record StopCluster(Location primary, Collection secondaries) { /** * Easily serializable version of a coordinate */ @@ -42,8 +39,8 @@ public record Location( Collection modes, List agencies, @Nullable FeedPublisher feedPublisher - ){ - public Location{ + ) { + public Location { Objects.requireNonNull(id); Objects.requireNonNull(name); Objects.requireNonNull(coordinate); diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index fd808d41bcf..2c5e4e1aa29 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -65,7 +65,11 @@ LuceneStopCluster map(StopLocationsGroup g) { var childStops = g.getChildStops(); var ids = childStops.stream().map(s -> s.getId().toString()).toList(); - var childNames = childStops.stream().map(StopLocation::getName).filter(Objects::nonNull).toList(); + var childNames = childStops + .stream() + .map(StopLocation::getName) + .filter(Objects::nonNull) + .toList(); var codes = childStops.stream().map(StopLocation::getCode).filter(Objects::nonNull).toList(); return new LuceneStopCluster( @@ -94,11 +98,11 @@ Optional map(StopLocation sl) { }); } - private List agenciesForStopLocation(StopLocation stop) { + List agenciesForStopLocation(StopLocation stop) { return transitService.getRoutesForStop(stop).stream().map(Route::getAgency).distinct().toList(); } - private List agenciesForStopLocationsGroup(StopLocationsGroup group) { + List agenciesForStopLocationsGroup(StopLocationsGroup group) { return group .getChildStops() .stream() diff --git a/src/main/java/org/opentripplanner/framework/collection/ListUtils.java b/src/main/java/org/opentripplanner/framework/collection/ListUtils.java index 302df428d12..5964a1674e3 100644 --- a/src/main/java/org/opentripplanner/framework/collection/ListUtils.java +++ b/src/main/java/org/opentripplanner/framework/collection/ListUtils.java @@ -63,10 +63,9 @@ public static List distinctByKey( * return a list with one element. */ public static List ofNullable(T input) { - if(input == null){ + if (input == null) { return List.of(); - } - else { + } else { return List.of(input); } } diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupOfStations.java b/src/main/java/org/opentripplanner/transit/model/site/GroupOfStations.java index c62d6099c97..66b45317718 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupOfStations.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupOfStations.java @@ -51,6 +51,12 @@ public WgsCoordinate getCoordinate() { return coordinate; } + @Nullable + @Override + public String getCode() { + return null; + } + @Nonnull public Collection getChildStops() { return this.childStations.stream().flatMap(s -> s.getChildStops().stream()).toList(); diff --git a/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java b/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java index 3536f59e9b6..70b2ee45a81 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java +++ b/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java @@ -1,6 +1,7 @@ package org.opentripplanner.transit.model.site; import java.util.Collection; +import javax.annotation.Nullable; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.lang.ObjectUtils; @@ -39,4 +40,7 @@ default double getLon() { default String logName() { return ObjectUtils.ifNotNull(getName(), Object::toString, null); } + + @Nullable + String getCode(); } From b4805c58b42af2c27a56ebd4b82b68056c991c2d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 22 May 2024 12:47:29 +0200 Subject: [PATCH 19/35] Move mapping code --- .../ext/geocoder/LuceneIndex.java | 45 +------------------ .../ext/geocoder/StopClusterMapper.java | 43 ++++++++++++++++++ 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index c39d18d6c22..689b7419122 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -40,7 +40,6 @@ import org.apache.lucene.search.suggest.document.FuzzyCompletionQuery; import org.apache.lucene.search.suggest.document.SuggestIndexSearcher; import org.apache.lucene.store.ByteBuffersDirectory; -import org.opentripplanner.ext.geocoder.StopCluster.Coordinate; import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.standalone.api.OtpServerRequestContext; @@ -186,53 +185,11 @@ public Stream queryStopClusters(String query) { private StopCluster toStopCluster(Document document) { var primaryId = FeedScopedId.parse(document.get(ID)); - var primary = toLocation(primaryId); + var primary = stopClusterMapper.toLocation(primaryId); return new StopCluster(primary, List.of()); } - private StopCluster.Location toLocation(FeedScopedId id) { - var loc = transitService.getStopLocation(id); - if (loc != null) { - var feedPublisher = StopClusterMapper.toFeedPublisher( - transitService.getFeedInfo(id.getFeedId()) - ); - var agencies = stopClusterMapper - .agenciesForStopLocation(loc) - .stream() - .map(StopClusterMapper::toAgency) - .toList(); - return new StopCluster.Location( - loc.getId(), - loc.getCode(), - loc.getName().toString(), - new Coordinate(loc.getLat(), loc.getLon()), - List.of(), - agencies, - feedPublisher - ); - } else { - var group = transitService.getStopLocationsGroup(id); - var feedPublisher = StopClusterMapper.toFeedPublisher( - transitService.getFeedInfo(id.getFeedId()) - ); - var agencies = stopClusterMapper - .agenciesForStopLocationsGroup(group) - .stream() - .map(StopClusterMapper::toAgency) - .toList(); - return new StopCluster.Location( - group.getId(), - group.getCode(), - group.getName().toString(), - new Coordinate(group.getLat(), group.getLon()), - List.of(), - agencies, - feedPublisher - ); - } - } - static IndexWriterConfig iwcWithSuggestField(Analyzer analyzer, final Set suggestFields) { IndexWriterConfig iwc = new IndexWriterConfig(analyzer); Codec filterCodec = new Lucene99Codec() { diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index 2c5e4e1aa29..543f06949ff 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -9,6 +9,7 @@ import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.model.FeedInfo; +import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.StopLocation; @@ -127,5 +128,47 @@ static StopCluster.FeedPublisher toFeedPublisher(FeedInfo fi) { } } + StopCluster.Location toLocation(FeedScopedId id) { + var loc = transitService.getStopLocation(id); + if (loc != null) { + var feedPublisher = toFeedPublisher( + transitService.getFeedInfo(id.getFeedId()) + ); + var modes = transitService.getModesOfStopLocation(loc).stream().map(Enum::name).toList(); + var agencies = agenciesForStopLocation(loc) + .stream() + .map(StopClusterMapper::toAgency) + .toList(); + return new StopCluster.Location( + loc.getId(), + loc.getCode(), + loc.getName().toString(), + new StopCluster.Coordinate(loc.getLat(), loc.getLon()), + modes, + agencies, + feedPublisher + ); + } else { + var group = transitService.getStopLocationsGroup(id); + var feedPublisher = toFeedPublisher( + transitService.getFeedInfo(id.getFeedId()) + ); + var modes = transitService.getModesOfStopLocationsGroup(group).stream().map(Enum::name).toList(); + var agencies = agenciesForStopLocationsGroup(group) + .stream() + .map(StopClusterMapper::toAgency) + .toList(); + return new StopCluster.Location( + group.getId(), + group.getCode(), + group.getName().toString(), + new StopCluster.Coordinate(group.getLat(), group.getLon()), + modes, + agencies, + feedPublisher + ); + } + } + private record DeduplicationKey(I18NString name, WgsCoordinate coordinate) {} } From f78d9c96ff2e7b4d6de06f00f2154baae7c24b1a Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 22 May 2024 15:43:37 +0200 Subject: [PATCH 20/35] Also add secondaries from stop clusters --- .../ext/geocoder/LuceneIndex.java | 41 ++++---- .../ext/geocoder/LuceneStopCluster.java | 1 - .../ext/geocoder/StopClusterMapper.java | 99 ++++++++++--------- 3 files changed, 71 insertions(+), 70 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java index 689b7419122..e0ea8ba36b9 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneIndex.java @@ -52,14 +52,13 @@ public class LuceneIndex implements Serializable { private static final String TYPE = "type"; private static final String ID = "id"; + private static final String SECONDARY_IDS = "secondary_ids"; private static final String SUGGEST = "suggest"; private static final String NAME = "name"; private static final String NAME_NGRAM = "name_ngram"; private static final String CODE = "code"; private static final String LAT = "latitude"; private static final String LON = "longitude"; - private static final String MODE = "mode"; - private static final String AGENCY_IDS = "agency_ids"; private final TransitService transitService; private final Analyzer analyzer; @@ -96,12 +95,11 @@ public LuceneIndex(TransitService transitService) { directoryWriter, StopLocation.class, stopLocation.getId().toString(), + List.of(), ListUtils.ofNullable(stopLocation.getName()), ListUtils.ofNullable(stopLocation.getCode()), stopLocation.getCoordinate().latitude(), - stopLocation.getCoordinate().longitude(), - Set.of(), - Set.of() + stopLocation.getCoordinate().longitude() ) ); @@ -112,12 +110,11 @@ public LuceneIndex(TransitService transitService) { directoryWriter, StopLocationsGroup.class, stopLocationsGroup.getId().toString(), + List.of(), ListUtils.ofNullable(stopLocationsGroup.getName()), List.of(), stopLocationsGroup.getCoordinate().latitude(), - stopLocationsGroup.getCoordinate().longitude(), - Set.of(), - Set.of() + stopLocationsGroup.getCoordinate().longitude() ) ); @@ -131,12 +128,11 @@ public LuceneIndex(TransitService transitService) { directoryWriter, StopCluster.class, stopCluster.primaryId(), + stopCluster.secondaryIds(), stopCluster.names(), stopCluster.codes(), stopCluster.coordinate().lat(), - stopCluster.coordinate().lon(), - stopCluster.modes(), - List.of() + stopCluster.coordinate().lon() ) ); } @@ -187,7 +183,13 @@ private StopCluster toStopCluster(Document document) { var primaryId = FeedScopedId.parse(document.get(ID)); var primary = stopClusterMapper.toLocation(primaryId); - return new StopCluster(primary, List.of()); + var secondaryIds = Arrays + .stream(document.getValues(SECONDARY_IDS)) + .map(FeedScopedId::parse) + .map(stopClusterMapper::toLocation) + .toList(); + + return new StopCluster(primary, secondaryIds); } static IndexWriterConfig iwcWithSuggestField(Analyzer analyzer, final Set suggestFields) { @@ -211,17 +213,19 @@ private static void addToIndex( IndexWriter writer, Class type, String id, + Collection secondaryIds, Collection names, Collection codes, double latitude, - double longitude, - Collection modes, - Collection agencyIds + double longitude ) { String typeName = type.getSimpleName(); Document document = new Document(); document.add(new StoredField(ID, id)); + for (var secondaryId : secondaryIds) { + document.add(new StoredField(SECONDARY_IDS, secondaryId)); + } document.add(new TextField(TYPE, typeName, Store.YES)); for (var name : names) { document.add(new TextField(NAME, Objects.toString(name), Store.YES)); @@ -236,13 +240,6 @@ private static void addToIndex( document.add(new ContextSuggestField(SUGGEST, code, 1, typeName)); } - for (var mode : modes) { - document.add(new TextField(MODE, mode, Store.YES)); - } - for (var aId : agencyIds) { - document.add(new TextField(AGENCY_IDS, aId, Store.YES)); - } - try { writer.addDocument(document); } catch (IOException ex) { diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java index 9ed1b71da76..b4ee0f0919b 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/LuceneStopCluster.java @@ -10,7 +10,6 @@ record LuceneStopCluster( String primaryId, Collection secondaryIds, Collection names, - Collection modes, Collection codes, StopCluster.Coordinate coordinate ) {} diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index 543f06949ff..bb8f0e72bbe 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; @@ -39,7 +40,7 @@ Iterable generateStopClusters( Collection stopLocations, Collection stopLocationsGroups ) { - var stops = stopLocations + List stops = stopLocations .stream() // remove stop locations without a parent station .filter(sl -> sl.getParentStation() == null) @@ -48,13 +49,17 @@ Iterable generateStopClusters( .toList(); // if they are very close to each other and have the same name, only one is chosen (at random) - var deduplicatedStops = ListUtils - .distinctByKey( - stops, - sl -> new DeduplicationKey(sl.getName(), sl.getCoordinate().roundToApproximate100m()) + var deduplicatedStops = stops + .stream() + .collect( + Collectors.groupingBy(sl -> + new DeduplicationKey(sl.getName(), sl.getCoordinate().roundToApproximate100m()) + ) ) + .values() .stream() - .flatMap(s -> this.map(s).stream()) + .map(group -> this.map(group).orElse(null)) + .filter(Objects::nonNull) .toList(); var stations = stopLocationsGroups.stream().map(this::map).toList(); @@ -62,8 +67,6 @@ Iterable generateStopClusters( } LuceneStopCluster map(StopLocationsGroup g) { - var modes = transitService.getModesOfStopLocationsGroup(g).stream().map(Enum::name).toList(); - var childStops = g.getChildStops(); var ids = childStops.stream().map(s -> s.getId().toString()).toList(); var childNames = childStops @@ -78,32 +81,34 @@ LuceneStopCluster map(StopLocationsGroup g) { ids, ListUtils.combine(List.of(g.getName()), childNames), codes, - modes, toCoordinate(g.getCoordinate()) ); } - Optional map(StopLocation sl) { + Optional map(List stopLocations) { + var primary = stopLocations.getFirst(); + var secondaryIds = stopLocations.stream().skip(1).map(sl -> sl.getId().toString()).toList(); + var names = stopLocations.stream().map(StopLocation::getName).toList(); + var codes = stopLocations.stream().map(StopLocation::getCode).filter(Objects::nonNull).toList(); + return Optional - .ofNullable(sl.getName()) - .map(name -> { - var modes = transitService.getModesOfStopLocation(sl).stream().map(Enum::name).toList(); - return new LuceneStopCluster( - sl.getId().toString(), - List.of(), - List.of(name), - modes, - ListUtils.ofNullable(sl.getCode()), - toCoordinate(sl.getCoordinate()) - ); - }); + .ofNullable(primary.getName()) + .map(name -> + new LuceneStopCluster( + primary.getId().toString(), + secondaryIds, + names, + codes, + toCoordinate(primary.getCoordinate()) + ) + ); } - List agenciesForStopLocation(StopLocation stop) { + private List agenciesForStopLocation(StopLocation stop) { return transitService.getRoutesForStop(stop).stream().map(Route::getAgency).distinct().toList(); } - List agenciesForStopLocationsGroup(StopLocationsGroup group) { + private List agenciesForStopLocationsGroup(StopLocationsGroup group) { return group .getChildStops() .stream() @@ -112,28 +117,10 @@ List agenciesForStopLocationsGroup(StopLocationsGroup group) { .toList(); } - private static StopCluster.Coordinate toCoordinate(WgsCoordinate c) { - return new StopCluster.Coordinate(c.latitude(), c.longitude()); - } - - static StopCluster.Agency toAgency(Agency a) { - return new StopCluster.Agency(a.getId(), a.getName()); - } - - static StopCluster.FeedPublisher toFeedPublisher(FeedInfo fi) { - if (fi == null) { - return null; - } else { - return new StopCluster.FeedPublisher(fi.getPublisherName()); - } - } - StopCluster.Location toLocation(FeedScopedId id) { var loc = transitService.getStopLocation(id); if (loc != null) { - var feedPublisher = toFeedPublisher( - transitService.getFeedInfo(id.getFeedId()) - ); + var feedPublisher = toFeedPublisher(transitService.getFeedInfo(id.getFeedId())); var modes = transitService.getModesOfStopLocation(loc).stream().map(Enum::name).toList(); var agencies = agenciesForStopLocation(loc) .stream() @@ -150,10 +137,12 @@ StopCluster.Location toLocation(FeedScopedId id) { ); } else { var group = transitService.getStopLocationsGroup(id); - var feedPublisher = toFeedPublisher( - transitService.getFeedInfo(id.getFeedId()) - ); - var modes = transitService.getModesOfStopLocationsGroup(group).stream().map(Enum::name).toList(); + var feedPublisher = toFeedPublisher(transitService.getFeedInfo(id.getFeedId())); + var modes = transitService + .getModesOfStopLocationsGroup(group) + .stream() + .map(Enum::name) + .toList(); var agencies = agenciesForStopLocationsGroup(group) .stream() .map(StopClusterMapper::toAgency) @@ -170,5 +159,21 @@ StopCluster.Location toLocation(FeedScopedId id) { } } + private static StopCluster.Coordinate toCoordinate(WgsCoordinate c) { + return new StopCluster.Coordinate(c.latitude(), c.longitude()); + } + + static StopCluster.Agency toAgency(Agency a) { + return new StopCluster.Agency(a.getId(), a.getName()); + } + + private static StopCluster.FeedPublisher toFeedPublisher(FeedInfo fi) { + if (fi == null) { + return null; + } else { + return new StopCluster.FeedPublisher(fi.getPublisherName()); + } + } + private record DeduplicationKey(I18NString name, WgsCoordinate coordinate) {} } From c27e8ce6f729054ad120c29ac21c6b8f870f05f5 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 29 May 2024 10:33:14 +0200 Subject: [PATCH 21/35] Add type to geocoding results --- .../java/org/opentripplanner/ext/geocoder/StopCluster.java | 7 +++++++ .../opentripplanner/ext/geocoder/StopClusterMapper.java | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java index 4c51c7586dd..30647cc7b20 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopCluster.java @@ -31,9 +31,15 @@ public record Agency(FeedScopedId id, String name) {} */ public record FeedPublisher(String name) {} + public enum LocationType { + STATION, + STOP, + } + public record Location( FeedScopedId id, @Nullable String code, + LocationType type, String name, Coordinate coordinate, Collection modes, @@ -43,6 +49,7 @@ public record Location( public Location { Objects.requireNonNull(id); Objects.requireNonNull(name); + Objects.requireNonNull(type); Objects.requireNonNull(coordinate); Objects.requireNonNull(modes); Objects.requireNonNull(agencies); diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index bb8f0e72bbe..de8d2681fd9 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -1,5 +1,8 @@ package org.opentripplanner.ext.geocoder; +import static org.opentripplanner.ext.geocoder.StopCluster.LocationType.STATION; +import static org.opentripplanner.ext.geocoder.StopCluster.LocationType.STOP; + import com.google.common.collect.Iterables; import java.util.Collection; import java.util.List; @@ -129,6 +132,7 @@ StopCluster.Location toLocation(FeedScopedId id) { return new StopCluster.Location( loc.getId(), loc.getCode(), + STOP, loc.getName().toString(), new StopCluster.Coordinate(loc.getLat(), loc.getLon()), modes, @@ -150,6 +154,7 @@ StopCluster.Location toLocation(FeedScopedId id) { return new StopCluster.Location( group.getId(), group.getCode(), + STATION, group.getName().toString(), new StopCluster.Coordinate(group.getLat(), group.getLon()), modes, From 78cd79b221ad92ba051d812bd807d5f7a2fc990f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 29 May 2024 11:07:06 +0200 Subject: [PATCH 22/35] Add test for ofNullable --- .../opentripplanner/framework/collection/ListUtilsTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/java/org/opentripplanner/framework/collection/ListUtilsTest.java b/src/test/java/org/opentripplanner/framework/collection/ListUtilsTest.java index 6e72d5626c5..33dce1f5574 100644 --- a/src/test/java/org/opentripplanner/framework/collection/ListUtilsTest.java +++ b/src/test/java/org/opentripplanner/framework/collection/ListUtilsTest.java @@ -56,5 +56,11 @@ void distinctByKey() { assertEquals(List.of(first, third), deduplicated); } + @Test + void ofNullable() { + assertEquals(List.of(), ListUtils.ofNullable(null)); + assertEquals(List.of("A"), ListUtils.ofNullable("A")); + } + private record Wrapper(int i, String string) {} } From 072210db36eed88a8ea759b56b42a151449a93b9 Mon Sep 17 00:00:00 2001 From: Henrik Abrahamsson Date: Tue, 28 May 2024 17:16:50 +0200 Subject: [PATCH 23/35] Add nicer assertions to SiriTimetableSnapshotSourceTest --- .../siri/SiriTimetableSnapshotSourceTest.java | 145 +++++++++++------- 1 file changed, 92 insertions(+), 53 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index fa1af949bd3..b74fde4ec31 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.opentripplanner.DateTimeHelper; +import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.StopTime; @@ -73,10 +74,11 @@ void testAddJourney() { var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); - var tripTimes = env.getTripTimesForTrip("newJourney"); - assertEquals(RealTimeState.ADDED, tripTimes.getRealTimeState()); - assertEquals(2 * 60, tripTimes.getDepartureTime(0)); - assertEquals(4 * 60, tripTimes.getDepartureTime(1)); + assertEquals("ADDED | C1 0:02 0:02 | D1 0:04 0:04", env.getRealtimeTimetable("newJourney")); + assertEquals( + "SCHEDULED | C1 0:01 0:01 | D1 0:03 0:03", + env.getScheduledTimetable("newJourney") + ); } @Test @@ -98,14 +100,13 @@ void testReplaceJourney() { assertEquals(1, result.successful()); - var tripTimes = env.getTripTimesForTrip("newJourney"); - var pattern = env.getPatternForTrip(env.id("newJourney")); - assertEquals(RealTimeState.ADDED, tripTimes.getRealTimeState()); - assertEquals(2 * 60, tripTimes.getDepartureTime(0)); - assertEquals(4 * 60, tripTimes.getDepartureTime(1)); - assertEquals(env.stopA1.getId(), pattern.getStop(0).getId()); - assertEquals(env.stopC1.getId(), pattern.getStop(1).getId()); + assertEquals("ADDED | A1 0:02 0:02 | C1 0:04 0:04", env.getRealtimeTimetable("newJourney")); + assertEquals( + "SCHEDULED | A1 0:01 0:01 | C1 0:03 0:03", + env.getScheduledTimetable("newJourney") + ); + // Original trip should not get canceled var originalTripTimes = env.getTripTimesForTrip(env.trip1); assertEquals(RealTimeState.SCHEDULED, originalTripTimes.getRealTimeState()); } @@ -123,6 +124,10 @@ void testUpdateJourneyWithDatedVehicleJourneyRef() { var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); assertTripUpdated(env); + assertEquals( + "UPDATED | A1 0:00:15 0:00:15 | B1 0:00:25 0:00:25", + env.getRealtimeTimetable(env.trip1) + ); } /** @@ -214,15 +219,10 @@ void testChangeQuay() { var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); - - var pattern = env.getPatternForTrip(env.trip1.getId()); - var tripTimes = env.getTripTimesForTrip(env.trip1); - assertEquals(RealTimeState.MODIFIED, tripTimes.getRealTimeState()); - assertEquals(11, tripTimes.getScheduledDepartureTime(0)); - assertEquals(15, tripTimes.getDepartureTime(0)); - assertEquals(20, tripTimes.getScheduledArrivalTime(1)); - assertEquals(33, tripTimes.getArrivalTime(1)); - assertEquals(env.stopB2, pattern.getStop(1)); + assertEquals( + "MODIFIED | A1 0:00:15 0:00:15 | B2 0:00:33 0:00:33", + env.getRealtimeTimetable(env.trip1) + ); } @Test @@ -245,12 +245,10 @@ void testCancelStop() { var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); - - var pattern = env.getPatternForTrip(env.trip2.getId()); - - assertEquals(PickDrop.SCHEDULED, pattern.getAlightType(0)); - assertEquals(PickDrop.CANCELLED, pattern.getAlightType(1)); - assertEquals(PickDrop.SCHEDULED, pattern.getAlightType(2)); + assertEquals( + "MODIFIED | A1 0:01:01 0:01:01 | B1 0:01:10 0:01:11 CANCELLED | C1 0:01:30 0:01:30", + env.getRealtimeTimetable(env.trip2) + ); } // TODO: support this @@ -278,23 +276,10 @@ void testAddStop() { var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); - - var pattern = env.getPatternForTrip(env.trip1.getId()); - var tripTimes = env.getTripTimesForTrip(env.trip1); - assertEquals(RealTimeState.MODIFIED, tripTimes.getRealTimeState()); - assertEquals(11, tripTimes.getScheduledDepartureTime(0)); - assertEquals(15, tripTimes.getDepartureTime(0)); - - // Should it work to get the scheduled times from an extra call? - assertEquals(19, tripTimes.getScheduledArrivalTime(1)); - assertEquals(24, tripTimes.getScheduledDepartureTime(1)); - - assertEquals(20, tripTimes.getDepartureTime(1)); - assertEquals(25, tripTimes.getDepartureTime(1)); - - assertEquals(20, tripTimes.getScheduledArrivalTime(2)); - assertEquals(33, tripTimes.getArrivalTime(2)); - assertEquals(List.of(env.stopA1, env.stopD1, env.stopB1), pattern.getStops()); + assertEquals( + "MODIFIED | A1 0:00:15 0:00:15 | D1 0:00:20 0:00:25 CANCELLED | B1 0:00:33 0:00:33", + env.getRealtimeTimetable(env.trip1) + ); } ///////////////// @@ -414,21 +399,20 @@ private void assertFailure(UpdateResult result, UpdateError.UpdateErrorType erro private static SiriEtBuilder updatedJourneyBuilder(RealtimeTestEnvironment env) { return new SiriEtBuilder(env.getDateTimeHelper()) - .withRecordedCalls(builder -> - builder.call(env.stopA1).departAimedActual("00:00:11", "00:00:15") - ) .withEstimatedCalls(builder -> - builder.call(env.stopB1).arriveAimedExpected("00:00:20", "00:00:25") + builder + .call(env.stopA1) + .departAimedExpected("00:00:11", "00:00:15") + .call(env.stopB1) + .arriveAimedExpected("00:00:20", "00:00:25") ); } private static void assertTripUpdated(RealtimeTestEnvironment env) { - var tripTimes = env.getTripTimesForTrip(env.trip1); - assertEquals(RealTimeState.UPDATED, tripTimes.getRealTimeState()); - assertEquals(11, tripTimes.getScheduledDepartureTime(0)); - assertEquals(15, tripTimes.getDepartureTime(0)); - assertEquals(20, tripTimes.getScheduledArrivalTime(1)); - assertEquals(25, tripTimes.getArrivalTime(1)); + assertEquals( + "UPDATED | A1 0:00:15 0:00:15 | B1 0:00:25 0:00:25", + env.getRealtimeTimetable(env.trip1) + ); } private static class RealtimeTestEnvironment { @@ -565,6 +549,61 @@ public TripTimes getTripTimesForTrip(Trip trip) { return getTripTimesForTrip(trip.getId(), serviceDate); } + public String getRealtimeTimetable(String tripId) { + return getRealtimeTimetable(id(tripId), serviceDate); + } + + public String getRealtimeTimetable(Trip trip) { + return getRealtimeTimetable(trip.getId(), serviceDate); + } + + public String getRealtimeTimetable(FeedScopedId tripId, LocalDate serviceDate) { + var tt = getTripTimesForTrip(tripId, serviceDate); + var pattern = getPatternForTrip(tripId); + + return encodeTimetable(tt, pattern); + } + + public String getScheduledTimetable(String tripId) { + return getScheduledTimetable(id(tripId)); + } + + public String getScheduledTimetable(FeedScopedId tripId) { + var pattern = getPatternForTrip(tripId); + var tt = pattern.getScheduledTimetable().getTripTimes(tripId); + + return encodeTimetable(tt, pattern); + } + + /** + * This encodes the times and information about stops in a readable way in order to simplify + * testing. The format is: + * + * REALTIME_STATE | stop1 arrivalTime departureTime [CANCELLED] | stop2 ... + */ + private String encodeTimetable(TripTimes tripTimes, TripPattern pattern) { + var stops = pattern.getStops(); + + StringBuilder s = new StringBuilder(tripTimes.getRealTimeState().toString()); + for (int i = 0; i < tripTimes.getNumStops(); i++) { + var depart = tripTimes.getDepartureTime(i); + var arrive = tripTimes.getArrivalTime(i); + + s + .append(" | ") + .append(stops.get(i).getName()) + .append(" ") + .append(TimeUtils.timeToStrCompact(arrive)) + .append(" ") + .append(TimeUtils.timeToStrCompact(depart)); + + if (tripTimes.isCancelledStop(i)) { + s.append(" CANCELLED"); + } + } + return s.toString(); + } + /** * Find the current TripTimes for a trip id on the default serviceDate */ From 399217c52ddca9d0238e9797955c9ac0e5d9df7d Mon Sep 17 00:00:00 2001 From: Henrik Abrahamsson Date: Wed, 29 May 2024 13:07:51 +0200 Subject: [PATCH 24/35] Add abbreviations for stop realtime states in test --- .../siri/SiriTimetableSnapshotSourceTest.java | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index b74fde4ec31..4098c633c5b 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -5,6 +5,7 @@ import java.time.Duration; import java.time.LocalDate; import java.time.ZoneId; +import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -14,7 +15,6 @@ import org.opentripplanner.DateTimeHelper; import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.model.PickDrop; import org.opentripplanner.model.StopTime; import org.opentripplanner.model.calendar.CalendarServiceData; import org.opentripplanner.transit.model._data.TransitModelForTest; @@ -74,7 +74,7 @@ void testAddJourney() { var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); - assertEquals("ADDED | C1 0:02 0:02 | D1 0:04 0:04", env.getRealtimeTimetable("newJourney")); + assertEquals("ADDED | C1 [R] 0:02 0:02 | D1 0:04 0:04", env.getRealtimeTimetable("newJourney")); assertEquals( "SCHEDULED | C1 0:01 0:01 | D1 0:03 0:03", env.getScheduledTimetable("newJourney") @@ -100,7 +100,7 @@ void testReplaceJourney() { assertEquals(1, result.successful()); - assertEquals("ADDED | A1 0:02 0:02 | C1 0:04 0:04", env.getRealtimeTimetable("newJourney")); + assertEquals("ADDED | A1 [R] 0:02 0:02 | C1 0:04 0:04", env.getRealtimeTimetable("newJourney")); assertEquals( "SCHEDULED | A1 0:01 0:01 | C1 0:03 0:03", env.getScheduledTimetable("newJourney") @@ -220,7 +220,7 @@ void testChangeQuay() { assertEquals(1, result.successful()); assertEquals( - "MODIFIED | A1 0:00:15 0:00:15 | B2 0:00:33 0:00:33", + "MODIFIED | A1 [R] 0:00:15 0:00:15 | B2 0:00:33 0:00:33", env.getRealtimeTimetable(env.trip1) ); } @@ -246,7 +246,7 @@ void testCancelStop() { assertEquals(1, result.successful()); assertEquals( - "MODIFIED | A1 0:01:01 0:01:01 | B1 0:01:10 0:01:11 CANCELLED | C1 0:01:30 0:01:30", + "MODIFIED | A1 0:01:01 0:01:01 | B1 [C] 0:01:10 0:01:11 | C1 0:01:30 0:01:30", env.getRealtimeTimetable(env.trip2) ); } @@ -277,7 +277,7 @@ void testAddStop() { assertEquals(1, result.successful()); assertEquals( - "MODIFIED | A1 0:00:15 0:00:15 | D1 0:00:20 0:00:25 CANCELLED | B1 0:00:33 0:00:33", + "MODIFIED | A1 0:00:15 0:00:15 | D1 [C] 0:00:20 0:00:25 | B1 0:00:33 0:00:33", env.getRealtimeTimetable(env.trip1) ); } @@ -579,7 +579,15 @@ public String getScheduledTimetable(FeedScopedId tripId) { * This encodes the times and information about stops in a readable way in order to simplify * testing. The format is: * - * REALTIME_STATE | stop1 arrivalTime departureTime [CANCELLED] | stop2 ... + *
+     * REALTIME_STATE | stop1 [FLAGS] arrivalTime departureTime | stop2 ...
+     *
+     * Where flags are:
+     * C: Canceled
+     * R: Recorded
+     * PI: Prediction Inaccurate
+     * ND: No Data
+     * 
*/ private String encodeTimetable(TripTimes tripTimes, TripPattern pattern) { var stops = pattern.getStops(); @@ -588,18 +596,29 @@ private String encodeTimetable(TripTimes tripTimes, TripPattern pattern) { for (int i = 0; i < tripTimes.getNumStops(); i++) { var depart = tripTimes.getDepartureTime(i); var arrive = tripTimes.getArrivalTime(i); + var flags = new ArrayList(); + if (tripTimes.isCancelledStop(i)) { + flags.add("C"); + } + if (tripTimes.isRecordedStop(i)) { + flags.add("R"); + } + if (tripTimes.isPredictionInaccurate(i)) { + flags.add("PI"); + } + if (tripTimes.isNoDataStop(i)) { + flags.add("ND"); + } + s.append(" | ").append(stops.get(i).getName()); + if (!flags.isEmpty()) { + s.append(" [").append(String.join(",", flags)).append("]"); + } s - .append(" | ") - .append(stops.get(i).getName()) .append(" ") .append(TimeUtils.timeToStrCompact(arrive)) .append(" ") .append(TimeUtils.timeToStrCompact(depart)); - - if (tripTimes.isCancelledStop(i)) { - s.append(" CANCELLED"); - } } return s.toString(); } From 5e1736cb4cab2ba39c6730338b2e047a889b5dce Mon Sep 17 00:00:00 2001 From: Henrik Abrahamsson Date: Wed, 29 May 2024 13:12:28 +0200 Subject: [PATCH 25/35] Switch expected-actual in assertFailure() --- .../siri/SiriTimetableSnapshotSourceTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index 4098c633c5b..cd80da6f842 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -157,7 +157,7 @@ void testUpdateJourneyWithoutJourneyRef() { var updates = updatedJourneyBuilder(env).buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); assertEquals(0, result.successful()); - assertFailure(result, UpdateError.UpdateErrorType.TRIP_NOT_FOUND); + assertFailure(UpdateError.UpdateErrorType.TRIP_NOT_FOUND, result); } /** @@ -196,7 +196,7 @@ void testUpdateJourneyWithFuzzyMatchingAndMissingAimedDepartureTime() { var result = env.applyEstimatedTimetableWithFuzzyMatcher(updates); assertEquals(0, result.successful(), "Should fail gracefully"); - assertFailure(result, UpdateError.UpdateErrorType.NO_FUZZY_TRIP_MATCH); + assertFailure(UpdateError.UpdateErrorType.NO_FUZZY_TRIP_MATCH, result); } /** @@ -296,7 +296,7 @@ void testNotMonitored() { var result = env.applyEstimatedTimetable(updates); - assertFailure(result, UpdateError.UpdateErrorType.NOT_MONITORED); + assertFailure(UpdateError.UpdateErrorType.NOT_MONITORED, result); } @Test @@ -321,7 +321,7 @@ void testReplaceJourneyWithoutEstimatedVehicleJourneyCode() { var result = env.applyEstimatedTimetable(updates); // TODO: this should have a more specific error type - assertFailure(result, UpdateError.UpdateErrorType.UNKNOWN); + assertFailure(UpdateError.UpdateErrorType.UNKNOWN, result); } @Test @@ -341,7 +341,7 @@ void testNegativeHopTime() { var result = env.applyEstimatedTimetable(updates); - assertFailure(result, UpdateError.UpdateErrorType.NEGATIVE_HOP_TIME); + assertFailure(UpdateError.UpdateErrorType.NEGATIVE_HOP_TIME, result); } @Test @@ -364,7 +364,7 @@ void testNegativeDwellTime() { var result = env.applyEstimatedTimetable(updates); - assertFailure(result, UpdateError.UpdateErrorType.NEGATIVE_DWELL_TIME); + assertFailure(UpdateError.UpdateErrorType.NEGATIVE_DWELL_TIME, result); } // TODO: support this @@ -390,11 +390,11 @@ void testExtraUnknownStop() { var result = env.applyEstimatedTimetable(updates); - assertFailure(result, UpdateError.UpdateErrorType.INVALID_STOP_SEQUENCE); + assertFailure(UpdateError.UpdateErrorType.INVALID_STOP_SEQUENCE, result); } - private void assertFailure(UpdateResult result, UpdateError.UpdateErrorType errorType) { - assertEquals(result.failures().keySet(), Set.of(errorType)); + private void assertFailure(UpdateError.UpdateErrorType expectedError, UpdateResult result) { + assertEquals(Set.of(expectedError), result.failures().keySet()); } private static SiriEtBuilder updatedJourneyBuilder(RealtimeTestEnvironment env) { From ec4baa396c994d0bd89aa6e7b1e5496353b92c93 Mon Sep 17 00:00:00 2001 From: Vincent Paturet Date: Thu, 30 May 2024 14:23:43 +0200 Subject: [PATCH 26/35] Add OTP request timeout GraphQL instrumentation --- .../OTPRequestTimeoutInstrumentation.java | 36 +++++++++++++++++++ .../apis/transmodel/TransmodelGraph.java | 5 ++- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/opentripplanner/apis/transmodel/OTPRequestTimeoutInstrumentation.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/OTPRequestTimeoutInstrumentation.java b/src/main/java/org/opentripplanner/apis/transmodel/OTPRequestTimeoutInstrumentation.java new file mode 100644 index 00000000000..acb27eb4e87 --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/transmodel/OTPRequestTimeoutInstrumentation.java @@ -0,0 +1,36 @@ +package org.opentripplanner.apis.transmodel; + +import static graphql.execution.instrumentation.SimpleInstrumentationContext.noOp; + +import graphql.execution.instrumentation.Instrumentation; +import graphql.execution.instrumentation.InstrumentationContext; +import graphql.execution.instrumentation.InstrumentationState; +import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; +import java.util.concurrent.atomic.AtomicLong; +import org.opentripplanner.framework.application.OTPRequestTimeoutException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A GraphQL instrumentation that periodically checks the OTP request interruption status while the + * query is being processed. + */ +public class OTPRequestTimeoutInstrumentation implements Instrumentation { + + private static final Logger LOG = LoggerFactory.getLogger(OTPRequestTimeoutInstrumentation.class); + + private final AtomicLong fieldFetchCounter = new AtomicLong(); + + @Override + public InstrumentationContext beginFieldFetch( + InstrumentationFieldFetchParameters parameters, + InstrumentationState state + ) { + long fetched = fieldFetchCounter.incrementAndGet(); + if (fetched % 100000 == 0) { + LOG.debug("Fetched {} fields", fetched); + OTPRequestTimeoutException.checkForTimeout(); + } + return noOp(); + } +} diff --git a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java b/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java index 051e369dde0..2cd405212c2 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraph.java @@ -79,7 +79,10 @@ Response executeGraphQL( } private static Instrumentation createInstrumentation(int maxResolves, Iterable tracingTags) { - Instrumentation instrumentation = new MaxQueryComplexityInstrumentation(maxResolves); + Instrumentation instrumentation = new ChainedInstrumentation( + new MaxQueryComplexityInstrumentation(maxResolves), + new OTPRequestTimeoutInstrumentation() + ); if (OTPFeature.ActuatorAPI.isOn()) { instrumentation = From ab5ec25ca1b86995bd567b9d2ec1ab1f1d514fc4 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 31 May 2024 10:39:18 +0200 Subject: [PATCH 27/35] Use cast to extract code --- .../ext/geocoder/StopClusterMapper.java | 13 ++++++++++++- .../transit/model/site/GroupOfStations.java | 6 ------ .../transit/model/site/StopLocationsGroup.java | 4 ---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index de8d2681fd9..fbb9941c59c 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -9,6 +9,7 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; +import javax.annotation.Nullable; import org.opentripplanner.framework.collection.ListUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; @@ -16,6 +17,7 @@ import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.organization.Agency; +import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.site.StopLocationsGroup; import org.opentripplanner.transit.service.TransitService; @@ -153,7 +155,7 @@ StopCluster.Location toLocation(FeedScopedId id) { .toList(); return new StopCluster.Location( group.getId(), - group.getCode(), + extractCode(group), STATION, group.getName().toString(), new StopCluster.Coordinate(group.getLat(), group.getLon()), @@ -164,6 +166,15 @@ StopCluster.Location toLocation(FeedScopedId id) { } } + @Nullable + private static String extractCode(StopLocationsGroup group) { + if (group instanceof Station station) { + return station.getCode(); + } else { + return null; + } + } + private static StopCluster.Coordinate toCoordinate(WgsCoordinate c) { return new StopCluster.Coordinate(c.latitude(), c.longitude()); } diff --git a/src/main/java/org/opentripplanner/transit/model/site/GroupOfStations.java b/src/main/java/org/opentripplanner/transit/model/site/GroupOfStations.java index 66b45317718..c62d6099c97 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/GroupOfStations.java +++ b/src/main/java/org/opentripplanner/transit/model/site/GroupOfStations.java @@ -51,12 +51,6 @@ public WgsCoordinate getCoordinate() { return coordinate; } - @Nullable - @Override - public String getCode() { - return null; - } - @Nonnull public Collection getChildStops() { return this.childStations.stream().flatMap(s -> s.getChildStops().stream()).toList(); diff --git a/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java b/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java index 70b2ee45a81..3536f59e9b6 100644 --- a/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java +++ b/src/main/java/org/opentripplanner/transit/model/site/StopLocationsGroup.java @@ -1,7 +1,6 @@ package org.opentripplanner.transit.model.site; import java.util.Collection; -import javax.annotation.Nullable; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.lang.ObjectUtils; @@ -40,7 +39,4 @@ default double getLon() { default String logName() { return ObjectUtils.ifNotNull(getName(), Object::toString, null); } - - @Nullable - String getCode(); } From a8571b473d420539a552f40950dfd59903d3bca0 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Fri, 31 May 2024 09:11:42 +0000 Subject: [PATCH 28/35] Add changelog entry for #5881 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 7b0982efd14..0c4356c99c8 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -23,6 +23,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Document and validate timeRange GraphQL parameter [#5834](https://github.com/opentripplanner/OpenTripPlanner/pull/5834) - Log the origin of a request that causes a transfer cache addition. [#5874](https://github.com/opentripplanner/OpenTripPlanner/pull/5874) - Fix handling of missing aimed departure time [#5865](https://github.com/opentripplanner/OpenTripPlanner/pull/5865) +- Add OTP request timeout GraphQL instrumentation [#5881](https://github.com/opentripplanner/OpenTripPlanner/pull/5881) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.5.0 (2024-03-13) From 6a73f0140556c0a4c99a731ec0f2c438028062fe Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 31 May 2024 23:52:15 +0200 Subject: [PATCH 29/35] Apply review feedback --- .../ext/geocoder/LuceneIndexTest.java | 14 +++++----- .../ext/geocoder/StopClusterMapper.java | 28 +++++++++++-------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java index 15f205ad802..cee6cf3a2d8 100644 --- a/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/geocoder/LuceneIndexTest.java @@ -277,17 +277,17 @@ void fuzzyStopCode(String query) { void modes() { var result = index.queryStopClusters("westh").toList(); assertEquals(1, result.size()); - var stop = result.getFirst(); - assertEquals(WESTHAFEN.getName().toString(), stop.primary().name()); - assertEquals(List.of(FERRY.name(), BUS.name()), stop.primary().modes()); + var cluster = result.getFirst(); + assertEquals(WESTHAFEN.getName().toString(), cluster.primary().name()); + assertEquals(List.of(FERRY.name(), BUS.name()), cluster.primary().modes()); } @Test void agenciesAndFeedPublisher() { - var result = index.queryStopClusters("alexanderplatz").toList().getFirst(); - assertEquals(ALEXANDERPLATZ_STATION.getName().toString(), result.primary().name()); - assertEquals(List.of(StopClusterMapper.toAgency(BVG)), result.primary().agencies()); - assertEquals("A Publisher", result.primary().feedPublisher().name()); + var cluster = index.queryStopClusters("alexanderplatz").toList().getFirst(); + assertEquals(ALEXANDERPLATZ_STATION.getName().toString(), cluster.primary().name()); + assertEquals(List.of(StopClusterMapper.toAgency(BVG)), cluster.primary().agencies()); + assertEquals("A Publisher", cluster.primary().feedPublisher().name()); } } diff --git a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java index fbb9941c59c..d9f388ea0e8 100644 --- a/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java +++ b/src/ext/java/org/opentripplanner/ext/geocoder/StopClusterMapper.java @@ -63,23 +63,19 @@ Iterable generateStopClusters( ) .values() .stream() - .map(group -> this.map(group).orElse(null)) + .map(group -> map(group).orElse(null)) .filter(Objects::nonNull) .toList(); - var stations = stopLocationsGroups.stream().map(this::map).toList(); + var stations = stopLocationsGroups.stream().map(StopClusterMapper::map).toList(); return Iterables.concat(deduplicatedStops, stations); } - LuceneStopCluster map(StopLocationsGroup g) { + private static LuceneStopCluster map(StopLocationsGroup g) { var childStops = g.getChildStops(); var ids = childStops.stream().map(s -> s.getId().toString()).toList(); - var childNames = childStops - .stream() - .map(StopLocation::getName) - .filter(Objects::nonNull) - .toList(); - var codes = childStops.stream().map(StopLocation::getCode).filter(Objects::nonNull).toList(); + var childNames = getNames(childStops); + var codes = getCodes(childStops); return new LuceneStopCluster( g.getId().toString(), @@ -90,11 +86,19 @@ LuceneStopCluster map(StopLocationsGroup g) { ); } - Optional map(List stopLocations) { + private static List getCodes(Collection childStops) { + return childStops.stream().map(StopLocation::getCode).filter(Objects::nonNull).toList(); + } + + private static List getNames(Collection childStops) { + return childStops.stream().map(StopLocation::getName).filter(Objects::nonNull).toList(); + } + + private static Optional map(List stopLocations) { var primary = stopLocations.getFirst(); var secondaryIds = stopLocations.stream().skip(1).map(sl -> sl.getId().toString()).toList(); - var names = stopLocations.stream().map(StopLocation::getName).toList(); - var codes = stopLocations.stream().map(StopLocation::getCode).filter(Objects::nonNull).toList(); + var names = getNames(stopLocations); + var codes = getCodes(stopLocations); return Optional .ofNullable(primary.getName()) From 170abf8dbfbdd950d94748448cf28e37acb5da69 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 31 May 2024 21:53:24 +0000 Subject: [PATCH 30/35] chore(deps): update dependency com.google.cloud.tools:jib-maven-plugin to v3.4.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c06bfcafeb1..90bfffb731a 100644 --- a/pom.xml +++ b/pom.xml @@ -444,7 +444,7 @@ com.google.cloud.tools jib-maven-plugin - 3.4.2 + 3.4.3 org.opentripplanner.standalone.OTPMain From 4fafb1c30e62be754ef29ca293222ead97075c21 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 31 May 2024 21:53:29 +0000 Subject: [PATCH 31/35] chore(deps): update dependency org.apache.maven.plugins:maven-shade-plugin to v3.6.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 90bfffb731a..5880d9dcc62 100644 --- a/pom.xml +++ b/pom.xml @@ -363,7 +363,7 @@ properly if some input files are missing a terminating newline) --> org.apache.maven.plugins maven-shade-plugin - 3.5.3 + 3.6.0 package From f4e2fe229e90b0d4e26594ef8b77f698c5ad76e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 2 Jun 2024 01:10:47 +0000 Subject: [PATCH 32/35] chore(deps): update debug ui dependencies (non-major) --- client-next/package-lock.json | 155 ++++++++++++++++++---------------- client-next/package.json | 10 +-- 2 files changed, 87 insertions(+), 78 deletions(-) diff --git a/client-next/package-lock.json b/client-next/package-lock.json index 20e7e0b83c1..75fec4ca86c 100644 --- a/client-next/package-lock.json +++ b/client-next/package-lock.json @@ -26,21 +26,21 @@ "@testing-library/react": "15.0.7", "@types/react": "18.3.3", "@types/react-dom": "18.3.0", - "@typescript-eslint/eslint-plugin": "7.10.0", - "@typescript-eslint/parser": "7.10.0", + "@typescript-eslint/eslint-plugin": "7.11.0", + "@typescript-eslint/parser": "7.11.0", "@vitejs/plugin-react": "4.3.0", "@vitest/coverage-v8": "1.6.0", "eslint": "8.57.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-import": "2.29.1", "eslint-plugin-jsx-a11y": "6.8.0", - "eslint-plugin-react": "7.34.1", + "eslint-plugin-react": "7.34.2", "eslint-plugin-react-hooks": "4.6.2", "eslint-plugin-react-refresh": "0.4.7", "jsdom": "24.1.0", - "prettier": "3.2.5", + "prettier": "3.3.0", "typescript": "5.4.5", - "vite": "5.2.11", + "vite": "5.2.12", "vitest": "1.6.0" } }, @@ -3810,17 +3810,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.10.0.tgz", - "integrity": "sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz", + "integrity": "sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/type-utils": "7.10.0", - "@typescript-eslint/utils": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/type-utils": "7.11.0", + "@typescript-eslint/utils": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3844,16 +3844,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.10.0.tgz", - "integrity": "sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/typescript-estree": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/typescript-estree": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", "debug": "^4.3.4" }, "engines": { @@ -3873,14 +3873,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.10.0.tgz", - "integrity": "sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz", + "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0" + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3891,14 +3891,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.10.0.tgz", - "integrity": "sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz", + "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.10.0", - "@typescript-eslint/utils": "7.10.0", + "@typescript-eslint/typescript-estree": "7.11.0", + "@typescript-eslint/utils": "7.11.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -3919,9 +3919,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.10.0.tgz", - "integrity": "sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", + "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", "dev": true, "license": "MIT", "engines": { @@ -3933,14 +3933,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.10.0.tgz", - "integrity": "sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz", + "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3975,16 +3975,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.10.0.tgz", - "integrity": "sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.11.0.tgz", + "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/typescript-estree": "7.10.0" + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/typescript-estree": "7.11.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -3998,13 +3998,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.10.0.tgz", - "integrity": "sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", + "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/types": "7.11.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -5679,10 +5679,11 @@ } }, "node_modules/es-abstract": { - "version": "1.23.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", - "integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -5723,11 +5724,11 @@ "safe-regex-test": "^1.0.3", "string.prototype.trim": "^1.2.9", "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.7", + "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.2", "typed-array-byte-length": "^1.0.1", "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.5", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", "which-typed-array": "^1.1.15" }, @@ -5760,14 +5761,15 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.18", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", - "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", + "es-abstract": "^1.23.3", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", @@ -6135,29 +6137,30 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.34.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", - "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", + "version": "7.34.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.2.tgz", + "integrity": "sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==", "dev": true, + "license": "MIT", "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlast": "^1.2.4", + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.2", "array.prototype.toreversed": "^1.1.2", "array.prototype.tosorted": "^1.1.3", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.17", + "es-iterator-helpers": "^1.0.19", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7", - "object.hasown": "^1.1.3", - "object.values": "^1.1.7", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.hasown": "^1.1.4", + "object.values": "^1.2.0", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.10" + "string.prototype.matchall": "^4.0.11" }, "engines": { "node": ">=4" @@ -6193,6 +6196,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6203,6 +6207,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -6215,6 +6220,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6227,6 +6233,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -9379,10 +9386,11 @@ } }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz", + "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -11135,10 +11143,11 @@ } }, "node_modules/vite": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", - "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", + "version": "5.2.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.12.tgz", + "integrity": "sha512-/gC8GxzxMK5ntBwb48pR32GGhENnjtY30G4A0jemunsBkiEZFw60s8InGpN8gkhHEkjnRK1aSAxeQgwvFhUHAA==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "^0.20.1", "postcss": "^8.4.38", diff --git a/client-next/package.json b/client-next/package.json index 9195702c1ad..17171945476 100644 --- a/client-next/package.json +++ b/client-next/package.json @@ -35,21 +35,21 @@ "@testing-library/react": "15.0.7", "@types/react": "18.3.3", "@types/react-dom": "18.3.0", - "@typescript-eslint/eslint-plugin": "7.10.0", - "@typescript-eslint/parser": "7.10.0", + "@typescript-eslint/eslint-plugin": "7.11.0", + "@typescript-eslint/parser": "7.11.0", "@vitejs/plugin-react": "4.3.0", "@vitest/coverage-v8": "1.6.0", "eslint": "8.57.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-import": "2.29.1", "eslint-plugin-jsx-a11y": "6.8.0", - "eslint-plugin-react": "7.34.1", + "eslint-plugin-react": "7.34.2", "eslint-plugin-react-hooks": "4.6.2", "eslint-plugin-react-refresh": "0.4.7", "jsdom": "24.1.0", - "prettier": "3.2.5", + "prettier": "3.3.0", "typescript": "5.4.5", - "vite": "5.2.11", + "vite": "5.2.12", "vitest": "1.6.0" } } From b567ac52692efa9fe64b6bcb6be860be63def227 Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Mon, 3 Jun 2024 06:11:28 +0000 Subject: [PATCH 33/35] Upgrade debug client to version 2024/06/2024-06-03T06:10 --- src/client/debug-client-preview/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/debug-client-preview/index.html b/src/client/debug-client-preview/index.html index 91f07c43b9a..717fce1baf2 100644 --- a/src/client/debug-client-preview/index.html +++ b/src/client/debug-client-preview/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +
From 397818f50b2c6015df92e3c3ff8b2a6bcd046a23 Mon Sep 17 00:00:00 2001 From: Henrik Abrahamsson Date: Mon, 3 Jun 2024 08:46:29 +0200 Subject: [PATCH 34/35] Move TripTimesStringBuilder to core --- .../siri/SiriTimetableSnapshotSourceTest.java | 55 +--------------- .../timetable/TripTimesStringBuilder.java | 64 +++++++++++++++++++ 2 files changed, 67 insertions(+), 52 deletions(-) create mode 100644 src/main/java/org/opentripplanner/transit/model/timetable/TripTimesStringBuilder.java diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index cd80da6f842..cfe080c47dc 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -5,7 +5,6 @@ import java.time.Duration; import java.time.LocalDate; import java.time.ZoneId; -import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -13,7 +12,6 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.opentripplanner.DateTimeHelper; -import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; import org.opentripplanner.model.StopTime; import org.opentripplanner.model.calendar.CalendarServiceData; @@ -30,6 +28,7 @@ import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.model.timetable.TripTimesFactory; +import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.StopModel; import org.opentripplanner.transit.service.TransitModel; @@ -561,7 +560,7 @@ public String getRealtimeTimetable(FeedScopedId tripId, LocalDate serviceDate) { var tt = getTripTimesForTrip(tripId, serviceDate); var pattern = getPatternForTrip(tripId); - return encodeTimetable(tt, pattern); + return TripTimesStringBuilder.encodeTripTimes(tt, pattern); } public String getScheduledTimetable(String tripId) { @@ -572,55 +571,7 @@ public String getScheduledTimetable(FeedScopedId tripId) { var pattern = getPatternForTrip(tripId); var tt = pattern.getScheduledTimetable().getTripTimes(tripId); - return encodeTimetable(tt, pattern); - } - - /** - * This encodes the times and information about stops in a readable way in order to simplify - * testing. The format is: - * - *
-     * REALTIME_STATE | stop1 [FLAGS] arrivalTime departureTime | stop2 ...
-     *
-     * Where flags are:
-     * C: Canceled
-     * R: Recorded
-     * PI: Prediction Inaccurate
-     * ND: No Data
-     * 
- */ - private String encodeTimetable(TripTimes tripTimes, TripPattern pattern) { - var stops = pattern.getStops(); - - StringBuilder s = new StringBuilder(tripTimes.getRealTimeState().toString()); - for (int i = 0; i < tripTimes.getNumStops(); i++) { - var depart = tripTimes.getDepartureTime(i); - var arrive = tripTimes.getArrivalTime(i); - var flags = new ArrayList(); - if (tripTimes.isCancelledStop(i)) { - flags.add("C"); - } - if (tripTimes.isRecordedStop(i)) { - flags.add("R"); - } - if (tripTimes.isPredictionInaccurate(i)) { - flags.add("PI"); - } - if (tripTimes.isNoDataStop(i)) { - flags.add("ND"); - } - - s.append(" | ").append(stops.get(i).getName()); - if (!flags.isEmpty()) { - s.append(" [").append(String.join(",", flags)).append("]"); - } - s - .append(" ") - .append(TimeUtils.timeToStrCompact(arrive)) - .append(" ") - .append(TimeUtils.timeToStrCompact(depart)); - } - return s.toString(); + return TripTimesStringBuilder.encodeTripTimes(tt, pattern); } /** diff --git a/src/main/java/org/opentripplanner/transit/model/timetable/TripTimesStringBuilder.java b/src/main/java/org/opentripplanner/transit/model/timetable/TripTimesStringBuilder.java new file mode 100644 index 00000000000..a5e77037dea --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/model/timetable/TripTimesStringBuilder.java @@ -0,0 +1,64 @@ +package org.opentripplanner.transit.model.timetable; + +import java.util.ArrayList; +import org.opentripplanner.framework.time.TimeUtils; +import org.opentripplanner.transit.model.network.TripPattern; + +public class TripTimesStringBuilder { + + /** + * This encodes the trip times and information about stops in a readable way in order to simplify + * testing/debugging. The format of the outputput string is: + * + *
+   * REALTIME_STATE | stop1 [FLAGS] arrivalTime departureTime | stop2 ...
+   *
+   * Where flags are:
+   * C: Canceled
+   * R: Recorded
+   * PI: Prediction Inaccurate
+   * ND: No Data
+   * 
+ * + * @throws IllegalStateException if TripTimes does not match the TripPattern + */ + public static String encodeTripTimes(TripTimes tripTimes, TripPattern pattern) { + var stops = pattern.getStops(); + + if (tripTimes.getNumStops() != stops.size()) { + throw new IllegalArgumentException( + "TripTimes and TripPattern have different number of stops" + ); + } + + StringBuilder s = new StringBuilder(tripTimes.getRealTimeState().toString()); + for (int i = 0; i < tripTimes.getNumStops(); i++) { + var depart = tripTimes.getDepartureTime(i); + var arrive = tripTimes.getArrivalTime(i); + var flags = new ArrayList(); + if (tripTimes.isCancelledStop(i)) { + flags.add("C"); + } + if (tripTimes.isRecordedStop(i)) { + flags.add("R"); + } + if (tripTimes.isPredictionInaccurate(i)) { + flags.add("PI"); + } + if (tripTimes.isNoDataStop(i)) { + flags.add("ND"); + } + + s.append(" | ").append(stops.get(i).getName()); + if (!flags.isEmpty()) { + s.append(" [").append(String.join(",", flags)).append("]"); + } + s + .append(" ") + .append(TimeUtils.timeToStrCompact(arrive)) + .append(" ") + .append(TimeUtils.timeToStrCompact(depart)); + } + return s.toString(); + } +} From dd4a76ae2db7331d02f3f700331e8ec14b60e4f8 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Mon, 3 Jun 2024 09:14:24 +0000 Subject: [PATCH 35/35] Add changelog entry for #5835 [ci skip] --- docs/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index 0c4356c99c8..9df32c081af 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -24,6 +24,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Log the origin of a request that causes a transfer cache addition. [#5874](https://github.com/opentripplanner/OpenTripPlanner/pull/5874) - Fix handling of missing aimed departure time [#5865](https://github.com/opentripplanner/OpenTripPlanner/pull/5865) - Add OTP request timeout GraphQL instrumentation [#5881](https://github.com/opentripplanner/OpenTripPlanner/pull/5881) +- Add feed publisher name and url to GTFS GraphQL API [#5835](https://github.com/opentripplanner/OpenTripPlanner/pull/5835) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.5.0 (2024-03-13)