All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentripplanner.transit.raptor.rangeraptor.transit.SearchContext Maven / Gradle / Ivy

There is a newer version: 2.5.0
Show newest version
package org.opentripplanner.transit.raptor.rangeraptor.transit;

import org.opentripplanner.transit.raptor.api.debug.DebugLogger;
import org.opentripplanner.transit.raptor.api.request.DebugRequest;
import org.opentripplanner.transit.raptor.api.request.McCostParams;
import org.opentripplanner.transit.raptor.api.request.RaptorProfile;
import org.opentripplanner.transit.raptor.api.request.RaptorRequest;
import org.opentripplanner.transit.raptor.api.request.RaptorTuningParameters;
import org.opentripplanner.transit.raptor.api.request.SearchParams;
import org.opentripplanner.transit.raptor.api.transit.CostCalculator;
import org.opentripplanner.transit.raptor.api.transit.RaptorTransfer;
import org.opentripplanner.transit.raptor.api.transit.RaptorTransitDataProvider;
import org.opentripplanner.transit.raptor.api.transit.RaptorTripPattern;
import org.opentripplanner.transit.raptor.api.transit.RaptorTripSchedule;
import org.opentripplanner.transit.raptor.rangeraptor.RoundProvider;
import org.opentripplanner.transit.raptor.rangeraptor.SlackProvider;
import org.opentripplanner.transit.raptor.rangeraptor.WorkerLifeCycle;
import org.opentripplanner.transit.raptor.rangeraptor.debug.DebugHandlerFactory;
import org.opentripplanner.transit.raptor.rangeraptor.debug.WorkerPerformanceTimers;
import org.opentripplanner.transit.raptor.rangeraptor.path.ForwardPathMapper;
import org.opentripplanner.transit.raptor.rangeraptor.path.PathMapper;
import org.opentripplanner.transit.raptor.rangeraptor.path.ReversePathMapper;
import org.opentripplanner.transit.raptor.rangeraptor.workerlifecycle.LifeCycleEventPublisher;
import org.opentripplanner.transit.raptor.rangeraptor.workerlifecycle.LifeCycleSubscriptions;

import java.util.Collection;
import java.util.function.ToIntFunction;

/**
 * The search context is used to hold search scoped instances and to pass these
 * to who ever need them.
 *
 * @param  The TripSchedule type defined by the user of the raptor API.
 */
public class SearchContext {
    private static final DebugLogger NOOP_DEBUG_LOGGER = (topic, message) -> { };
    /**
     * The request input used to customize the worker to the clients needs.
     */
    private final RaptorRequest request;

    /**
     * the transit data role needed for routing
     */
    protected final RaptorTransitDataProvider transit;

    private final TransitCalculator calculator;
    private final CostCalculator costCalculator;
    private final RaptorTuningParameters tuningParameters;
    private final RoundTracker roundTracker;
    private final PathMapper pathMapper;
    private final WorkerPerformanceTimers timers;
    private final DebugHandlerFactory debugFactory;

    private final LifeCycleSubscriptions lifeCycleSubscriptions = new LifeCycleSubscriptions();

    public SearchContext(
            RaptorRequest request,
            RaptorTuningParameters tuningParameters,
            RaptorTransitDataProvider transit,
            WorkerPerformanceTimers timers
    ) {
        this.request = request;
        this.tuningParameters = tuningParameters;
        this.transit = transit;
        // Note that it is the "new" request that is passed in.
        this.calculator = createCalculator(this.request, tuningParameters);
        this.costCalculator = createCostCalculator(
            transit.stopBoarAlightCost(),
            request.multiCriteriaCostFactors(),
            lifeCycle()
        );
        this.roundTracker = new RoundTracker(
            nRounds(),
            request.searchParams().numberOfAdditionalTransfers(),
            lifeCycle()
        );
        this.pathMapper = createPathMapper(request, lifeCycle());
        this.timers = timers;
        this.debugFactory = new DebugHandlerFactory<>(debugRequest(request), lifeCycle());
    }

    public Collection accessLegs() {
        return request.searchDirection().isForward()
                ? request.searchParams().accessLegs()
                : request.searchParams().egressLegs();
    }

    public Collection egressLegs() {
        return request.searchDirection().isForward()
                ? request.searchParams().egressLegs()
                : request.searchParams().accessLegs();
    }

    public int[] egressStops() {
        return egressLegs().stream().mapToInt(RaptorTransfer::stop).toArray();
    }

    public SearchParams searchParams() {
        return request.searchParams();
    }

    public RaptorProfile profile() {
        return request.profile();
    }

    public RaptorTransitDataProvider transit() {
        return transit;
    }

    public TransitCalculator calculator() {
        return calculator;
    }

    /**
     * Create new slack-provider for use in Raptor, handles reverse and forward
     * search as well as including transfer-slack into board-slack between transits.
     * 

* The {@code SlackProvider} is stateful, so this method create a new instance * every time it is called, so each consumer could have their own instance and * not get surprised by the life-cycle update. */ public SlackProvider slackProvider() { return createSlackProvider(request, lifeCycle()); } /** * The board-slack (duration time in seconds) to add to the stop arrival time, * before boarding the given trip pattern. THIS DO NOT INCLUDE THE transfer-slack, * and should only be used to time-shift the access-leg. *

* Unit: seconds. */ public ToIntFunction boardSlackProvider() { return createBoardSlackProvider(request); } public PathMapper pathMapper() { return pathMapper; } public CostCalculator costCalculator() { return costCalculator; } public WorkerPerformanceTimers timers() { return timers; } public DebugHandlerFactory debugFactory() { return debugFactory; } public DebugLogger debugLogger() { DebugLogger logger = request.debug().logger(); return logger != null ? logger : NOOP_DEBUG_LOGGER; } /** Number of stops in transit graph. */ public int nStops() { return transit.numberOfStops(); } /** Calculate the maximum number of rounds to perform. */ public int nRounds() { if(request.searchParams().isMaxNumberOfTransfersSet()) { return request.searchParams().maxNumberOfTransfers() + 1; } return tuningParameters.maxNumberOfTransfers() + 1; } public RoundProvider roundProvider() { return roundTracker; } public WorkerLifeCycle lifeCycle() { return lifeCycleSubscriptions; } public LifeCycleEventPublisher createLifeCyclePublisher() { LifeCycleEventPublisher publisher = new LifeCycleEventPublisher(lifeCycleSubscriptions); // We want the code to fail if someone try to attach to the worker lifecycle // after it is initialized; Hence close for new subscriptions lifeCycleSubscriptions.close(); return publisher; } /* private methods */ /** * Create a new calculator depending on the desired search direction. */ private static TransitCalculator createCalculator(RaptorRequest r, RaptorTuningParameters t) { SearchParams s = r.searchParams(); return r.searchDirection().isForward() ? new ForwardTransitCalculator(s, t) : new ReverseTransitCalculator(s, t); } private static DebugRequest debugRequest( RaptorRequest request ) { return request.searchDirection().isForward() ? request.debug() : request.mutate().debug().reverseDebugRequest().build(); } private static SlackProvider createSlackProvider( RaptorRequest request, WorkerLifeCycle lifeCycle ) { return request.searchDirection().isForward() ? new ForwardSlackProvider<>(request.slackProvider(), lifeCycle) : new ReverseSlackProvider<>(request.slackProvider(), lifeCycle); } private static ToIntFunction createBoardSlackProvider( RaptorRequest request ) { return request.searchDirection().isForward() ? p -> request.slackProvider().boardSlack(p) : p -> request.slackProvider().alightSlack(p); } private static PathMapper createPathMapper( RaptorRequest request, WorkerLifeCycle lifeCycle ) { return request.searchDirection().isForward() ? new ForwardPathMapper<>(lifeCycle) : new ReversePathMapper<>(lifeCycle); } private static CostCalculator createCostCalculator( int[] stopVisitCost, McCostParams f, WorkerLifeCycle lifeCycle ) { return new DefaultCostCalculator<>( stopVisitCost, f.boardCost(), f.walkReluctanceFactor(), f.waitReluctanceFactor(), lifeCycle ); } }