use of org.opentripplanner.routing.algorithm.raptor.transit.TransitLayer in project OpenTripPlanner by opentripplanner.
the class Router method startup.
/*
* Below is functionality moved into Router from the "router lifecycle manager" interface and implementation.
* Current responsibilities are: 1) Binding proper services (depending on the configuration from command-line or
* JSON config files) and 2) starting / stopping real-time updaters (delegated to the GraphUpdaterConfigurator class).
*/
/**
* Start up a new router once it has been created.
*/
public void startup() {
this.tileRendererManager = new TileRendererManager(this.graph);
this.defaultRoutingRequest = routerConfig.routingRequestDefaults();
if (routerConfig.requestLogFile() != null) {
this.requestLogger = createLogger(routerConfig.requestLogFile());
LOG.info("Logging incoming requests at '{}'", routerConfig.requestLogFile());
} else {
LOG.info("Incoming requests will not be logged.");
}
/* Create transit layer for Raptor routing. Here we map the scheduled timetables. */
/* Realtime updates can be mapped similarly by a recurring operation in a GraphUpdater below. */
LOG.info("Creating transit layer for Raptor routing.");
if (graph.hasTransit && graph.index != null) {
graph.setTransitLayer(TransitLayerMapper.map(routerConfig.transitTuningParameters(), graph));
graph.setRealtimeTransitLayer(new TransitLayer(graph.getTransitLayer()));
graph.transitLayerUpdater = new TransitLayerUpdater(graph, graph.index.getServiceCodesRunningForDate());
} else {
LOG.warn("Cannot create Raptor data, that requires the graph to have transit data and be indexed.");
}
/* Create Graph updater modules from JSON config. */
GraphUpdaterConfigurator.setupGraph(this.graph, routerConfig.updaterConfig());
/* Compute ellipsoidToGeoidDifference for this Graph */
try {
WorldEnvelope env = graph.getEnvelope();
double lat = (env.getLowerLeftLatitude() + env.getUpperRightLatitude()) / 2;
double lon = (env.getLowerLeftLongitude() + env.getUpperRightLongitude()) / 2;
graph.ellipsoidToGeoidDifference = ElevationUtils.computeEllipsoidToGeoidDifference(lat, lon);
LOG.info("Computed ellipsoid/geoid offset at (" + lat + ", " + lon + ") as " + graph.ellipsoidToGeoidDifference);
} catch (Exception e) {
LOG.error("Error computing ellipsoid/geoid difference");
}
if (OTPFeature.SandboxAPITransmodelApi.isOn()) {
TransmodelAPI.setUp(routerConfig.transmodelApiHideFeedId(), graph, defaultRoutingRequest);
}
}
use of org.opentripplanner.routing.algorithm.raptor.transit.TransitLayer in project OpenTripPlanner by opentripplanner.
the class TransitLayerMapper method map.
private TransitLayer map(TransitTuningParameters tuningParameters) {
StopIndexForRaptor stopIndex;
HashMap<LocalDate, List<TripPatternForDate>> tripPatternsByStopByDate;
List<List<Transfer>> transferByStopIndex;
LOG.info("Mapping transitLayer from Graph...");
stopIndex = new StopIndexForRaptor(graph.index.getAllStops(), tuningParameters);
tripPatternsByStopByDate = mapTripPatterns(stopIndex);
transferByStopIndex = mapTransfers(stopIndex, graph.transfersByStop);
LOG.info("Mapping complete.");
return new TransitLayer(tripPatternsByStopByDate, transferByStopIndex, stopIndex, graph.getTimeZone().toZoneId());
}
use of org.opentripplanner.routing.algorithm.raptor.transit.TransitLayer in project OpenTripPlanner by opentripplanner.
the class TransitLayerUpdater method update.
public void update(Set<Timetable> updatedTimetables) {
if (!graph.hasRealtimeTransitLayer()) {
return;
}
// 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(graph.getRealtimeTransitLayer());
double startTime = System.currentTimeMillis();
// Map TripPatterns for this update to Raptor TripPatterns
final Map<org.opentripplanner.model.TripPattern, TripPatternWithRaptorStopIndexes> newTripPatternForOld = mapOldTripPatternToRaptorTripPattern(realtimeTransitLayer.getStopIndex(), updatedTimetables.stream().map(t -> t.pattern).collect(Collectors.toSet()));
// Instantiate a TripPatternForDateMapper with the new TripPattern mappings
TripPatternForDateMapper tripPatternForDateMapper = new TripPatternForDateMapper(serviceCodesRunningForDate, newTripPatternForOld);
// Index updated timetables by date
@SuppressWarnings("ConstantConditions") Multimap<LocalDate, Timetable> timetablesByDate = Multimaps.index(updatedTimetables, t -> ServiceCalendarMapper.localDateFromServiceDate(t.serviceDate));
for (LocalDate date : timetablesByDate.keySet()) {
Collection<Timetable> timetablesForDate = timetablesByDate.get(date);
List<TripPatternForDate> patternsForDate = realtimeTransitLayer.getTripPatternsForDateCopy(date);
if (patternsForDate == null) {
continue;
}
Map<org.opentripplanner.model.TripPattern, TripPatternForDate> patternsForDateMap = tripPatternForDateMapCache.computeIfAbsent(date, p -> patternsForDate.stream().collect(Collectors.toMap(t -> t.getTripPattern().getPattern(), t -> t)));
for (Timetable timetable : timetablesForDate) {
TripPatternForDate tripPatternForDate = tripPatternForDateMapper.map(timetable, timetable.serviceDate);
if (tripPatternForDate != null) {
patternsForDateMap.put(timetable.pattern, tripPatternForDate);
}
}
realtimeTransitLayer.replaceTripPatternsForDate(date, new ArrayList<>(patternsForDateMap.values()));
// 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.
graph.setRealtimeTransitLayer(realtimeTransitLayer);
LOG.debug("UPDATING {} tripPatterns took {} ms", updatedTimetables.size(), System.currentTimeMillis() - startTime);
}
}
use of org.opentripplanner.routing.algorithm.raptor.transit.TransitLayer in project OpenTripPlanner by opentripplanner.
the class RoutingWorker method routeTransit.
private Collection<Itinerary> routeTransit(Router router) {
request.setRoutingContext(router.graph);
if (request.modes.transitModes.isEmpty()) {
return Collections.emptyList();
}
if (!router.graph.transitFeedCovers(request.dateTime)) {
throw new RoutingValidationException(List.of(new RoutingError(RoutingErrorCode.OUTSIDE_SERVICE_PERIOD, InputField.DATE_TIME)));
}
TransitLayer transitLayer = request.ignoreRealtimeUpdates ? router.graph.getTransitLayer() : router.graph.getRealtimeTransitLayer();
RaptorRoutingRequestTransitData requestTransitDataProvider;
requestTransitDataProvider = new RaptorRoutingRequestTransitData(transitLayer, request.getDateTime().toInstant(), ADDITIONAL_SEARCH_DAYS_BEFORE_TODAY, ADDITIONAL_SEARCH_DAYS_AFTER_TODAY, request.modes.transitModes, request.rctx.bannedRoutes, request.walkSpeed);
this.debugAggregator.finishedPatternFiltering();
// Prepare access/egress transfers
Collection<AccessEgress> accessTransfers = AccessEgressRouter.streetSearch(request, false, 2000, transitLayer.getStopIndex());
Collection<AccessEgress> egressTransfers = AccessEgressRouter.streetSearch(request, true, 2000, transitLayer.getStopIndex());
verifyEgressAccess(accessTransfers, egressTransfers);
this.debugAggregator.finishedAccessEgress();
// Prepare transit search
RaptorRequest<TripSchedule> raptorRequest = RaptorRequestMapper.mapRequest(request, requestTransitDataProvider.getStartOfTime(), accessTransfers, egressTransfers);
// Route transit
RaptorResponse<TripSchedule> transitResponse = raptorService.route(raptorRequest, requestTransitDataProvider);
LOG.debug("Found {} transit itineraries", transitResponse.paths().size());
LOG.debug("Transit search params used: {}", transitResponse.requestUsed().searchParams());
this.debugAggregator.finishedRaptorSearch();
// Create itineraries
RaptorPathToItineraryMapper itineraryMapper = new RaptorPathToItineraryMapper(transitLayer, requestTransitDataProvider.getStartOfTime(), request);
FareService fareService = request.getRoutingContext().graph.getService(FareService.class);
List<Itinerary> itineraries = new ArrayList<>();
for (Path<TripSchedule> path : transitResponse.paths()) {
// Convert the Raptor/Astar paths to OTP API Itineraries
Itinerary itinerary = itineraryMapper.createItinerary(path);
// fare calculation. We derive the fares from the internal Path objects and add them to the itinerary.
if (fareService != null) {
itinerary.fare = fareService.getCost(path, transitLayer);
}
itineraries.add(itinerary);
}
checkIfTransitConnectionExists(transitResponse);
// Filter itineraries away that depart after the latest-departure-time for depart after
// search. These itineraries is a result of time-shifting the access leg and is needed for
// the raptor to prune the results. These itineraries are often not ideal, but if they
// pareto optimal for the "next" window, they will appear when a "next" search is performed.
searchWindowUsedInSeconds = transitResponse.requestUsed().searchParams().searchWindowInSeconds();
if (!request.arriveBy && searchWindowUsedInSeconds > 0) {
filterOnLatestDepartureTime = Instant.ofEpochSecond(request.dateTime + searchWindowUsedInSeconds);
}
this.debugAggregator.finishedItineraryCreation();
return itineraries;
}
Aggregations