diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/AddedTripBuilderTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/AddedTripBuilderTest.java index e322b0ddea9..59995062eb7 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/AddedTripBuilderTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/AddedTripBuilderTest.java @@ -154,37 +154,33 @@ void testAddedTrip() { assertEquals(SubMode.of(SUB_MODE), route.getNetexSubmode(), "submode should be mapped"); assertNotEquals(REPLACED_ROUTE, route, "Should not re-use replaced route"); - // Assert transit model index - var transitModelIndex = TRANSIT_MODEL.getTransitModelIndex(); - assertNotNull(transitModelIndex); assertEquals( route, - transitModelIndex.getRouteForId(TransitModelForTest.id(LINE_REF)), + transitService.getRouteForId(TransitModelForTest.id(LINE_REF)), "Route should be added to transit index" ); assertEquals( trip, - transitModelIndex.getTripForId().get(TRIP_ID), + transitService.getTripForId(TRIP_ID), "Route should be added to transit index" ); - var pattern = transitModelIndex.getPatternForTrip().get(trip); + var pattern = transitService.getPatternForTrip(trip); assertNotNull(pattern); assertEquals(route, pattern.getRoute()); assertTrue( - transitModelIndex - .getServiceCodesRunningForDate() - .get(SERVICE_DATE) + transitService + .getServiceCodesRunningForDate(SERVICE_DATE) .contains(TRANSIT_MODEL.getServiceCodes().get(trip.getServiceId())), "serviceId should be running on service date" ); assertNotNull( - transitModelIndex.getTripOnServiceDateById().get(TRIP_ID), + transitService.getTripOnServiceDateById(TRIP_ID), "TripOnServiceDate should be added to transit index by id" ); assertNotNull( - transitModelIndex - .getTripOnServiceDateForTripAndDay() - .get(new TripIdAndServiceDate(TRIP_ID, SERVICE_DATE)), + transitService.getTripOnServiceDateForTripAndDay( + new TripIdAndServiceDate(TRIP_ID, SERVICE_DATE) + ), "TripOnServiceDate should be added to transit index for trip and day" ); @@ -299,10 +295,7 @@ void testAddedTripOnAddedRoute() { Route route = secondTrip.getRoute(); assertSame(firstTrip.getRoute(), route, "route be reused from the first trip"); - // Assert transit model index - var transitModelIndex = TRANSIT_MODEL.getTransitModelIndex(); - assertNotNull(transitModelIndex); - assertEquals(2, transitModelIndex.getPatternsForRoute().get(route).size()); + assertEquals(2, transitService.getPatternsForRoute(route).size()); // Assert trip times var times = secondAddedTrip.successValue().tripTimes(); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/DirectTransferGenerator.java b/src/main/java/org/opentripplanner/graph_builder/module/DirectTransferGenerator.java index 287a1a71c21..3137b66070f 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/DirectTransferGenerator.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/DirectTransferGenerator.java @@ -67,9 +67,7 @@ public DirectTransferGenerator( @Override public void buildGraph() { /* Initialize transit model index which is needed by the nearby stop finder. */ - if (transitModel.getTransitModelIndex() == null) { - transitModel.index(); - } + transitModel.index(); /* The linker will use streets if they are available, or straight-line distance otherwise. */ NearbyStopFinder nearbyStopFinder = createNearbyStopFinder(); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransfersMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransfersMapper.java index 74a5d7a6352..c7e9ea05320 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransfersMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransfersMapper.java @@ -6,7 +6,7 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.Transfer; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.service.StopModel; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TransitService; class TransfersMapper { @@ -14,7 +14,7 @@ class TransfersMapper { * Copy pre-calculated transfers from the original graph * @return a list where each element is a list of transfers for the corresponding stop index */ - static List> mapTransfers(StopModel stopModel, TransitModel transitModel) { + static List> mapTransfers(StopModel stopModel, TransitService transitService) { List> transferByStopIndex = new ArrayList<>(); for (int i = 0; i < stopModel.stopIndexSize(); ++i) { @@ -26,7 +26,7 @@ static List> mapTransfers(StopModel stopModel, TransitModel trans ArrayList list = new ArrayList<>(); - for (PathTransfer pathTransfer : transitModel.getTransfersByStop(stop)) { + for (PathTransfer pathTransfer : transitService.getTransfersByStop(stop)) { if (pathTransfer.to instanceof RegularStop) { int toStopIndex = pathTransfer.to.getIndex(); Transfer newTransfer; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java index 33a076bb8d6..8ce328fe1b6 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerMapper.java @@ -27,8 +27,10 @@ import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.StopTransferPriority; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.StopModel; import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TransitService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,10 +49,12 @@ public class TransitLayerMapper { private static final Logger LOG = LoggerFactory.getLogger(TransitLayerMapper.class); - private final TransitModel transitModel; + private final TransitService transitService; + private final StopModel stopModel; private TransitLayerMapper(TransitModel transitModel) { - this.transitModel = transitModel; + this.transitService = new DefaultTransitService(transitModel); + this.stopModel = transitModel.getStopModel(); } public static TransitLayer map( @@ -74,20 +78,19 @@ private TransitLayer map(TransitTuningParameters tuningParameters) { HashMap> tripPatternsByStopByDate; List> transferByStopIndex; ConstrainedTransfersForPatterns constrainedTransfers = null; - StopModel stopModel = transitModel.getStopModel(); LOG.info("Mapping transitLayer from TransitModel..."); - Collection allTripPatterns = transitModel.getAllTripPatterns(); + Collection allTripPatterns = transitService.getAllTripPatterns(); tripPatternsByStopByDate = mapTripPatterns(allTripPatterns); - transferByStopIndex = mapTransfers(stopModel, transitModel); + transferByStopIndex = mapTransfers(stopModel, transitService); TransferIndexGenerator transferIndexGenerator = null; if (OTPFeature.TransferConstraints.isOn()) { transferIndexGenerator = - new TransferIndexGenerator(transitModel.getTransferService().listAll(), allTripPatterns); + new TransferIndexGenerator(transitService.getTransferService().listAll(), allTripPatterns); constrainedTransfers = transferIndexGenerator.generateTransfers(); } @@ -98,9 +101,9 @@ private TransitLayer map(TransitTuningParameters tuningParameters) { return new TransitLayer( tripPatternsByStopByDate, transferByStopIndex, - transitModel.getTransferService(), + transitService.getTransferService(), stopModel, - transitModel.getTimeZone(), + transitService.getTimeZone(), transferCache, constrainedTransfers, transferIndexGenerator, @@ -118,13 +121,10 @@ private HashMap> mapTripPatterns( Collection allTripPatterns ) { TripPatternForDateMapper tripPatternForDateMapper = new TripPatternForDateMapper( - transitModel.getTransitModelIndex().getServiceCodesRunningForDate() + transitService.getServiceCodesRunningForDate() ); - Set allServiceDates = transitModel - .getTransitModelIndex() - .getServiceCodesRunningForDate() - .keySet(); + Set allServiceDates = transitService.getAllServiceCodes(); List tripPatternForDates = Collections.synchronizedList(new ArrayList<>()); diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerUpdater.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerUpdater.java index 5188bdef8b1..934bec39c11 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerUpdater.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TransitLayerUpdater.java @@ -2,7 +2,6 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.SetMultimap; -import gnu.trove.set.TIntSet; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collection; @@ -20,7 +19,7 @@ import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.TripIdAndServiceDate; import org.opentripplanner.transit.model.timetable.TripTimes; -import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TransitEditorService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,9 +39,7 @@ public class TransitLayerUpdater { private static final Logger LOG = LoggerFactory.getLogger(TransitLayerUpdater.class); - private final TransitModel transitModel; - - private final Map serviceCodesRunningForDate; + private final TransitEditorService transitService; /** * Cache the TripPatternForDates indexed on the original TripPatterns in order to avoid this @@ -58,19 +55,15 @@ public class TransitLayerUpdater { private final Map> tripPatternsRunningOnDateMapCache = new HashMap<>(); - public TransitLayerUpdater( - TransitModel transitModel, - Map serviceCodesRunningForDate - ) { - this.transitModel = transitModel; - this.serviceCodesRunningForDate = serviceCodesRunningForDate; + public TransitLayerUpdater(TransitEditorService transitService) { + this.transitService = transitService; } public void update( Set updatedTimetables, Map> timetables ) { - if (!transitModel.hasRealtimeTransitLayer()) { + if (!transitService.hasRealtimeTransitLayer()) { return; } @@ -78,11 +71,11 @@ public void update( // Make a shallow copy of the realtime transit layer. Only the objects that are copied will be // changed during this update process. - TransitLayer realtimeTransitLayer = new TransitLayer(transitModel.getRealtimeTransitLayer()); + TransitLayer realtimeTransitLayer = new TransitLayer(transitService.getRealtimeTransitLayer()); // Instantiate a TripPatternForDateMapper with the new TripPattern mappings TripPatternForDateMapper tripPatternForDateMapper = new TripPatternForDateMapper( - serviceCodesRunningForDate + transitService.getServiceCodesRunningForDate() ); Set datesToBeUpdated = new HashSet<>(); @@ -229,7 +222,7 @@ public void update( // Switch out the reference with the updated realtimeTransitLayer. This is synchronized to // guarantee that the reference is set after all the fields have been updated. - transitModel.setRealtimeTransitLayer(realtimeTransitLayer); + transitService.setRealtimeTransitLayer(realtimeTransitLayer); LOG.debug( "UPDATING {} tripPatterns took {} ms", diff --git a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapper.java index 30551421138..cd00b9356dc 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/mappers/TripPatternForDateMapper.java @@ -41,7 +41,7 @@ public class TripPatternForDateMapper { * @param serviceCodesRunningForDate - READ ONLY */ TripPatternForDateMapper(Map serviceCodesRunningForDate) { - this.serviceCodesRunningForDate = Collections.unmodifiableMap(serviceCodesRunningForDate); + this.serviceCodesRunningForDate = serviceCodesRunningForDate; } /** diff --git a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java b/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java index b1bc6888753..7d07ca29f0e 100644 --- a/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java +++ b/src/main/java/org/opentripplanner/standalone/configure/ConstructApplication.java @@ -33,6 +33,7 @@ import org.opentripplanner.standalone.server.OTPWebApplication; import org.opentripplanner.street.model.StreetLimitationParameters; import org.opentripplanner.street.model.elevation.ElevationUtils; +import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.TransitModel; import org.opentripplanner.updater.configure.UpdaterConfigurator; import org.opentripplanner.visualizer.GraphVisualizer; @@ -202,7 +203,7 @@ public static void creatTransitLayerForRaptor( TransitModel transitModel, TransitTuningParameters tuningParameters ) { - if (!transitModel.hasTransit() || transitModel.getTransitModelIndex() == null) { + if (!transitModel.hasTransit() || !transitModel.isIndexed()) { LOG.warn( "Cannot create Raptor data, that requires the graph to have transit data and be indexed." ); @@ -211,10 +212,7 @@ public static void creatTransitLayerForRaptor( transitModel.setTransitLayer(TransitLayerMapper.map(tuningParameters, transitModel)); transitModel.setRealtimeTransitLayer(new TransitLayer(transitModel.getTransitLayer())); transitModel.setTransitLayerUpdater( - new TransitLayerUpdater( - transitModel, - transitModel.getTransitModelIndex().getServiceCodesRunningForDate() - ) + new TransitLayerUpdater(new DefaultTransitService(transitModel)) ); } diff --git a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java index 41d88726233..398cb806524 100644 --- a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java @@ -9,6 +9,7 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -594,6 +595,16 @@ public void setTransitLayer(TransitLayer transitLayer) { this.transitModel.setTransitLayer(transitLayer); } + @Override + public void setRealtimeTransitLayer(TransitLayer realtimeTransitLayer) { + transitModel.setRealtimeTransitLayer(realtimeTransitLayer); + } + + @Override + public boolean hasRealtimeTransitLayer() { + return transitModel.hasRealtimeTransitLayer(); + } + @Override public CalendarService getCalendarService() { return this.transitModel.getCalendarService(); @@ -659,6 +670,16 @@ public Deduplicator getDeduplicator() { return transitModel.getDeduplicator(); } + @Override + public Set getAllServiceCodes() { + return Collections.unmodifiableSet(transitModelIndex.getServiceCodesRunningForDate().keySet()); + } + + @Override + public Map getServiceCodesRunningForDate() { + return Collections.unmodifiableMap(transitModelIndex.getServiceCodesRunningForDate()); + } + /** * For each pattern visiting this {@link StopLocation} return its {@link TransitMode} */ diff --git a/src/main/java/org/opentripplanner/transit/service/TransitEditorService.java b/src/main/java/org/opentripplanner/transit/service/TransitEditorService.java index 6a11fe902f2..150d1749272 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitEditorService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitEditorService.java @@ -39,5 +39,22 @@ void addTripOnServiceDateForTripAndDay( FeedScopedId getOrCreateServiceIdForDate(LocalDate serviceDate); + /** + * Set the original, immutable, transit layer, + * based on scheduled data (not real-time data). + */ void setTransitLayer(TransitLayer transitLayer); + + /** + * Return true if a real-time transit layer is present. + * The real-time transit layer is optional, + * it is present only when real-time updaters are configured. + */ + boolean hasRealtimeTransitLayer(); + + /** + * Publish the latest snapshot of the real-time transit layer. + * Should be called only when creating a new TransitLayer, from the graph writer thread. + */ + void setRealtimeTransitLayer(TransitLayer realtimeTransitLayer); } diff --git a/src/main/java/org/opentripplanner/transit/service/TransitModel.java b/src/main/java/org/opentripplanner/transit/service/TransitModel.java index c5a36e54e3a..84c7597d562 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitModel.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitModel.java @@ -539,10 +539,15 @@ public void setHasScheduledService(boolean hasScheduledService) { * The caller is responsible for calling the {@link #index()} method if it is a * possibility that the index is not initialized (during graph build). */ - public @Nullable TransitModelIndex getTransitModelIndex() { + @Nullable + TransitModelIndex getTransitModelIndex() { return index; } + public boolean isIndexed() { + return index != null; + } + public boolean hasFlexTrips() { return !flexTripsById.isEmpty(); } diff --git a/src/main/java/org/opentripplanner/transit/service/TransitModelIndex.java b/src/main/java/org/opentripplanner/transit/service/TransitModelIndex.java index 333011e9baf..36ab937416c 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitModelIndex.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitModelIndex.java @@ -34,7 +34,7 @@ * For performance reasons these indexes are not part of the serialized state of the graph. * They are rebuilt at runtime after graph deserialization. */ -public class TransitModelIndex { +class TransitModelIndex { private static final Logger LOG = LoggerFactory.getLogger(TransitModelIndex.class); @@ -117,20 +117,20 @@ public class TransitModelIndex { LOG.info("Transit Model index init complete."); } - public Agency getAgencyForId(FeedScopedId id) { + Agency getAgencyForId(FeedScopedId id) { return agencyForId.get(id); } - public Route getRouteForId(FeedScopedId id) { + Route getRouteForId(FeedScopedId id) { return routeForId.get(id); } - public void addRoutes(Route route) { + void addRoutes(Route route) { routeForId.put(route.getId(), route); } /** Dynamically generate the set of Routes passing though a Stop on demand. */ - public Set getRoutesForStop(StopLocation stop) { + Set getRoutesForStop(StopLocation stop) { Set routes = new HashSet<>(); for (TripPattern p : getPatternsForStop(stop)) { routes.add(p.getRoute()); @@ -138,11 +138,11 @@ public Set getRoutesForStop(StopLocation stop) { return routes; } - public Collection getPatternsForStop(StopLocation stop) { + Collection getPatternsForStop(StopLocation stop) { return patternsForStopId.get(stop); } - public Collection getTripsForStop(StopLocation stop) { + Collection getTripsForStop(StopLocation stop) { return getPatternsForStop(stop) .stream() .flatMap(TripPattern::scheduledTripsAsStream) @@ -152,43 +152,43 @@ public Collection getTripsForStop(StopLocation stop) { /** * Get a list of all operators spanning across all feeds. */ - public Collection getAllOperators() { + Collection getAllOperators() { return getOperatorForId().values(); } - public Map getOperatorForId() { + Map getOperatorForId() { return operatorForId; } - public Map getTripForId() { + Map getTripForId() { return tripForId; } - public Map getTripOnServiceDateById() { + Map getTripOnServiceDateById() { return tripOnServiceDateById; } - public Map getTripOnServiceDateForTripAndDay() { + Map getTripOnServiceDateForTripAndDay() { return tripOnServiceDateForTripAndDay; } - public Collection getAllRoutes() { + Collection getAllRoutes() { return routeForId.values(); } - public Map getPatternForTrip() { + Map getPatternForTrip() { return patternForTrip; } - public Multimap getPatternsForRoute() { + Multimap getPatternsForRoute() { return patternsForRoute; } - public Map getServiceCodesRunningForDate() { + Map getServiceCodesRunningForDate() { return serviceCodesRunningForDate; } - public FlexIndex getFlexIndex() { + FlexIndex getFlexIndex() { return flexIndex; } @@ -229,11 +229,11 @@ private void initalizeServiceCodesForDate(TransitModel transitModel) { } } - public Multimap getRoutesForGroupOfRoutes() { + Multimap getRoutesForGroupOfRoutes() { return routesForGroupOfRoutes; } - public Map getGroupOfRoutesForId() { + Map getGroupOfRoutesForId() { return groupOfRoutesForId; } } diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/src/main/java/org/opentripplanner/transit/service/TransitService.java index 6624cb946ad..94870643f71 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -8,8 +8,10 @@ import java.time.ZonedDateTime; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; +import javax.annotation.Nullable; import org.locationtech.jts.geom.Envelope; import org.opentripplanner.ext.flex.FlexIndex; import org.opentripplanner.model.FeedInfo; @@ -188,6 +190,7 @@ List stopTimesForPatternAtStop( * Return the timetable for a given trip pattern and date, taking into account real-time updates. * If no real-times update are applied, fall back to scheduled data. */ + @Nullable Timetable getTimetableForTripPattern(TripPattern tripPattern, LocalDate serviceDate); TripPattern getRealtimeAddedTripPattern(FeedScopedId tripId, LocalDate serviceDate); @@ -254,4 +257,8 @@ List stopTimesForPatternAtStop( List getModesOfStopLocation(StopLocation stop); Deduplicator getDeduplicator(); + + Set getAllServiceCodes(); + + Map getServiceCodesRunningForDate(); } diff --git a/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java b/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java index 745418f5132..f1355ca0fa4 100644 --- a/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java +++ b/src/main/java/org/opentripplanner/updater/vehicle_position/PollingVehiclePositionUpdater.java @@ -3,13 +3,13 @@ import com.google.transit.realtime.GtfsRealtime.VehiclePosition; import java.time.LocalDate; import java.util.List; -import java.util.Optional; import org.opentripplanner.framework.tostring.ToStringBuilder; import org.opentripplanner.service.realtimevehicles.RealtimeVehicleRepository; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.updater.GtfsRealtimeFuzzyTripMatcher; import org.opentripplanner.updater.spi.PollingGraphUpdater; import org.opentripplanner.updater.spi.WriteToGraphCallback; @@ -45,18 +45,20 @@ public PollingVehiclePositionUpdater( super(params); this.vehiclePositionSource = new GtfsRealtimeHttpVehiclePositionSource(params.url(), params.headers()); - var index = transitModel.getTransitModelIndex(); + // TODO Inject TransitService, do not create it here. We currently do not + // support dagger injection in updaters, so this is ok for now. + TransitService transitService = new DefaultTransitService(transitModel); var fuzzyTripMatcher = params.fuzzyTripMatching() - ? new GtfsRealtimeFuzzyTripMatcher(new DefaultTransitService(transitModel)) + ? new GtfsRealtimeFuzzyTripMatcher(transitService) : null; this.realtimeVehiclePatternMatcher = new RealtimeVehiclePatternMatcher( params.feedId(), - tripId -> index.getTripForId().get(tripId), - trip -> index.getPatternForTrip().get(trip), + transitService::getTripForId, + transitService::getPatternForTrip, (trip, date) -> getPatternIncludingRealtime(transitModel, trip, date), realtimeVehicleRepository, - transitModel.getTimeZone(), + transitService.getTimeZone(), fuzzyTripMatcher, params.vehiclePositionFeatures() ); @@ -99,9 +101,8 @@ private static TripPattern getPatternIncludingRealtime( Trip trip, LocalDate sd ) { - return Optional - .ofNullable(transitModel.getTimetableSnapshot()) - .map(snapshot -> snapshot.getRealtimeAddedTripPattern(trip.getId(), sd)) - .orElseGet(() -> transitModel.getTransitModelIndex().getPatternForTrip().get(trip)); + // a new instance of DefaultTransitService must be created to retrieve + // the current TimetableSnapshot + return (new DefaultTransitService(transitModel)).getPatternForTrip(trip, sd); } } diff --git a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java b/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java index 2fb7a8d9db2..79590ca2775 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java +++ b/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java @@ -93,6 +93,7 @@ import org.opentripplanner.transit.model.timetable.RealTimeTripTimes; import org.opentripplanner.transit.model.timetable.TripTimesFactory; import org.opentripplanner.transit.service.DefaultTransitService; +import org.opentripplanner.transit.service.TransitEditorService; import org.opentripplanner.transit.service.TransitModel; import org.opentripplanner.transit.service.TransitService; @@ -196,8 +197,20 @@ static void setup() { .toList(); var busRoute = routes.stream().filter(r -> r.getMode().equals(BUS)).findFirst().get(); + TransitEditorService transitService = new DefaultTransitService(transitModel) { + private final TransitAlertService alertService = new TransitAlertServiceImpl(transitModel); + + @Override + public List getModesOfStopLocation(StopLocation stop) { + return List.of(BUS, FERRY); + } - routes.forEach(route -> transitModel.getTransitModelIndex().addRoutes(route)); + @Override + public TransitAlertService getTransitAlertService() { + return alertService; + } + }; + routes.forEach(transitService::addRoutes); var step1 = walkStep("street") .withRelativeDirection(RelativeDirection.DEPART) @@ -254,20 +267,6 @@ static void setup() { var emissions = new Emissions(new Grams(123.0)); i1.setEmissionsPerPerson(emissions); - var transitService = new DefaultTransitService(transitModel) { - private final TransitAlertService alertService = new TransitAlertServiceImpl(transitModel); - - @Override - public List getModesOfStopLocation(StopLocation stop) { - return List.of(BUS, FERRY); - } - - @Override - public TransitAlertService getTransitAlertService() { - return alertService; - } - }; - var alerts = ListUtils.combine(List.of(alert), getTransitAlert(entitySelector)); transitService.getTransitAlertService().setAlerts(alerts); diff --git a/src/test/java/org/opentripplanner/routing/graph/DefaultRoutingServiceTest.java b/src/test/java/org/opentripplanner/routing/graph/DefaultRoutingServiceTest.java index e9d286d5a92..8c56bb89a1f 100644 --- a/src/test/java/org/opentripplanner/routing/graph/DefaultRoutingServiceTest.java +++ b/src/test/java/org/opentripplanner/routing/graph/DefaultRoutingServiceTest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Collection; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Envelope; @@ -18,6 +19,8 @@ import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.service.DefaultTransitService; +import org.opentripplanner.transit.service.TransitService; /** * Check that the graph index is created, that GTFS elements can be found in the index, and that the @@ -27,6 +30,15 @@ */ public class DefaultRoutingServiceTest extends GtfsTest { + private TransitService transitService; + + @BeforeEach + @Override + public void setUp() throws Exception { + super.setUp(); + transitService = new DefaultTransitService(transitModel); + } + @Override public String getFeedName() { return "gtfs/simple"; @@ -44,16 +56,16 @@ public void testIdLookup() { } /* Agencies */ - String feedId = transitModel.getFeedIds().iterator().next(); + String feedId = transitService.getFeedIds().iterator().next(); Agency agency; - agency = transitModel.getTransitModelIndex().getAgencyForId(new FeedScopedId(feedId, "azerty")); + agency = transitService.getAgencyForId(new FeedScopedId(feedId, "azerty")); assertNull(agency); - agency = transitModel.getTransitModelIndex().getAgencyForId(new FeedScopedId(feedId, "agency")); + agency = transitService.getAgencyForId(new FeedScopedId(feedId, "agency")); assertEquals(feedId + ":" + "agency", agency.getId().toString()); assertEquals("Fake Agency", agency.getName()); /* Stops */ - transitModel.getStopModel().getRegularStop(new FeedScopedId("X", "Y")); + transitService.getRegularStop(new FeedScopedId("X", "Y")); /* Trips */ // graph.index.tripForId; // graph.index.routeForId; @@ -67,21 +79,18 @@ public void testIdLookup() { */ @Test public void testPatternsCoherent() { - for (Trip trip : transitModel.getTransitModelIndex().getTripForId().values()) { - TripPattern pattern = transitModel.getTransitModelIndex().getPatternForTrip().get(trip); + for (Trip trip : transitService.getAllTrips()) { + TripPattern pattern = transitService.getPatternForTrip(trip); assertTrue(pattern.scheduledTripsAsStream().anyMatch(t -> t.equals(trip))); } /* This one depends on a feed where each TripPattern appears on only one route. */ - for (Route route : transitModel.getTransitModelIndex().getAllRoutes()) { - for (TripPattern pattern : transitModel - .getTransitModelIndex() - .getPatternsForRoute() - .get(route)) { + for (Route route : transitService.getAllRoutes()) { + for (TripPattern pattern : transitService.getPatternsForRoute(route)) { assertEquals(pattern.getRoute(), route); } } - for (var stop : transitModel.getStopModel().listStopLocations()) { - for (TripPattern pattern : transitModel.getTransitModelIndex().getPatternsForStop(stop)) { + for (var stop : transitService.listStopLocations()) { + for (TripPattern pattern : transitService.getPatternsForStop(stop)) { int stopPos = pattern.findStopPosition(stop); assertTrue(stopPos >= 0, "Stop position exist"); } @@ -90,13 +99,13 @@ public void testPatternsCoherent() { @Test public void testSpatialIndex() { - String feedId = transitModel.getFeedIds().iterator().next(); + String feedId = transitService.getFeedIds().iterator().next(); FeedScopedId idJ = new FeedScopedId(feedId, "J"); - var stopJ = transitModel.getStopModel().getRegularStop(idJ); + var stopJ = transitService.getRegularStop(idJ); FeedScopedId idL = new FeedScopedId(feedId, "L"); - var stopL = transitModel.getStopModel().getRegularStop(idL); + var stopL = transitService.getRegularStop(idL); FeedScopedId idM = new FeedScopedId(feedId, "M"); - var stopM = transitModel.getStopModel().getRegularStop(idM); + var stopM = transitService.getRegularStop(idM); TransitStopVertex stopvJ = graph.getStopVertexForStopId(idJ); TransitStopVertex stopvL = graph.getStopVertexForStopId(idL); TransitStopVertex stopvM = graph.getStopVertexForStopId(idM); @@ -106,7 +115,7 @@ public void testSpatialIndex() { SphericalDistanceLibrary.metersToLonDegrees(100, stopJ.getLat()), SphericalDistanceLibrary.metersToDegrees(100) ); - Collection stops = transitModel.getStopModel().findRegularStops(env); + Collection stops = transitService.findRegularStops(env); assertTrue(stops.contains(stopJ)); assertTrue(stops.contains(stopL)); assertTrue(stops.contains(stopM)); diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java index 34923fed9e4..6adce735fb0 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java @@ -217,7 +217,7 @@ public DateTimeHelper getDateTimeHelper() { } public TripPattern getPatternForTrip(Trip trip) { - return transitModel.getTransitModelIndex().getPatternForTrip().get(trip); + return getTransitService().getPatternForTrip(trip); } public TimetableSnapshot getTimetableSnapshot() { diff --git a/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotSourceTest.java b/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotSourceTest.java index 7ae7b7386f3..84b53c95f9c 100644 --- a/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotSourceTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotSourceTest.java @@ -33,7 +33,9 @@ import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.TransitModel; +import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.updater.GtfsRealtimeFuzzyTripMatcher; import org.opentripplanner.updater.TimetableSnapshotSourceParameters; @@ -48,6 +50,7 @@ public class TimetableSnapshotSourceTest { ) .build(); private TransitModel transitModel; + private TransitService transitService; private final GtfsRealtimeFuzzyTripMatcher TRIP_MATCHER_NOOP = null; @@ -57,8 +60,9 @@ public class TimetableSnapshotSourceTest { public void setUp() { TestOtpModel model = ConstantsForTests.buildGtfsGraph(ConstantsForTests.SIMPLE_GTFS); transitModel = model.transitModel(); + transitService = new DefaultTransitService(transitModel); - feedId = transitModel.getFeedIds().stream().findFirst().get(); + feedId = transitService.getFeedIds().stream().findFirst().get(); } @Test @@ -115,7 +119,7 @@ public void testHandleModifiedTrip() { tripDescriptorBuilder.setStartDate(ServiceDateUtils.asCompactString(SERVICE_DATE)); final long midnightSecondsSinceEpoch = ServiceDateUtils - .asStartOfService(SERVICE_DATE, transitModel.getTimeZone()) + .asStartOfService(SERVICE_DATE, transitService.getTimeZone()) .toEpochSecond(); final TripUpdate.Builder tripUpdateBuilder = TripUpdate.newBuilder(); @@ -224,11 +228,8 @@ public void testHandleModifiedTrip() { // Original trip pattern { final FeedScopedId tripId = new FeedScopedId(feedId, modifiedTripId); - final Trip trip = transitModel.getTransitModelIndex().getTripForId().get(tripId); - final TripPattern originalTripPattern = transitModel - .getTransitModelIndex() - .getPatternForTrip() - .get(trip); + final Trip trip = transitService.getTripForId(tripId); + final TripPattern originalTripPattern = transitService.getPatternForTrip(trip); final Timetable originalTimetableForToday = snapshot.resolve( originalTripPattern, diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java index 8d3984cc546..8371c5dda3a 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java @@ -62,7 +62,7 @@ void addedTripWithNewRoute() { assertEquals(TripUpdateBuilder.ROUTE_NAME, route.getName()); assertEquals(TransitMode.RAIL, route.getMode()); - var fromTransitModel = env.transitModel.getTransitModelIndex().getRouteForId(route.getId()); + var fromTransitModel = env.getTransitService().getRouteForId(route.getId()); assertEquals(fromTransitModel, route); assertEquals(PickDrop.CALL_AGENCY, pattern.getBoardType(0)); @@ -117,7 +117,7 @@ void repeatedlyAddedTripWithNewRoute() { var secondRoute = secondPattern.getRoute(); assertSame(firstRoute, secondRoute); - assertNotNull(env.transitModel.getTransitModelIndex().getRouteForId(firstRoute.getId())); + assertNotNull(env.getTransitService().getRouteForId(firstRoute.getId())); } private TripPattern assertAddedTrip(String tripId, RealtimeTestEnvironment env) { diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java index 53805939e40..5298853f36d 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java @@ -86,10 +86,7 @@ void complexDelay() { var snapshot = env.getTimetableSnapshot(); - final TripPattern originalTripPattern = env.transitModel - .getTransitModelIndex() - .getPatternForTrip() - .get(env.trip2); + final TripPattern originalTripPattern = env.getTransitService().getPatternForTrip(env.trip2); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE); var originalTimetableScheduled = snapshot.resolve(originalTripPattern, null); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java index c17130fbda6..de699324bb6 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java @@ -132,8 +132,8 @@ private static void assertOriginalTripPatternIsDeleted( RealtimeTestEnvironment env, FeedScopedId tripId ) { - var trip = env.transitModel.getTransitModelIndex().getTripForId().get(tripId); - var originalTripPattern = env.transitModel.getTransitModelIndex().getPatternForTrip().get(trip); + var trip = env.getTransitService().getTripForId(tripId); + var originalTripPattern = env.getTransitService().getPatternForTrip(trip); var snapshot = env.getTimetableSnapshot(); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE); var originalTimetableScheduled = snapshot.resolve(originalTripPattern, null); @@ -178,10 +178,7 @@ private static void assertNewTripTimesIsUpdated( RealtimeTestEnvironment env, FeedScopedId tripId ) { - var originalTripPattern = env.transitModel - .getTransitModelIndex() - .getPatternForTrip() - .get(env.trip2); + var originalTripPattern = env.getTransitService().getPatternForTrip(env.trip2); var snapshot = env.getTimetableSnapshot(); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE);