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

org.opentripplanner.profile.PatternRide Maven / Gradle / Ivy

package org.opentripplanner.profile;

import org.opentripplanner.model.Stop;
import org.opentripplanner.routing.edgetype.TripPattern;

/**
 * A ride between two stops on a single pattern. One or more PatternRides can be included in a Ride.
 * Each Pattern needs its own separate PatternRide because stop indexes may be different on every
 * pattern of a route, and we need to store indexes rather than stop objects because a stop can
 * appear more than once in a pattern. When a ride is unfinished (waiting in the queue for
 * exploration in the next round) its toIndex is -1 and its stats field is null.
 */
class PatternRide {
    
    final TripPattern pattern; // TripPatterns use identity equality
    final int fromIndex;       // Always set, even on unfinished PatternRides
    final int toIndex;  // set when PatternRide is finished by extending it to a specific stop
    final Stats stats;  // set when PatternRide is finished by extending it to a specific stop
    
    @Override
    public boolean equals(Object o){
    	if(o==this) return true;
    	if (!(o instanceof PatternRide)) return false;
    	PatternRide other = (PatternRide) o;
    	if(!other.pattern.equals(this.pattern)) return false;
    	if(other.fromIndex != fromIndex) return false;
    	if(other.toIndex != toIndex) return false;
    	if(!other.stats.equals(this.stats)) return false;
    	return true;
    }

    /** Construct an unfinished PatternRide, lacking a toIndex and stats. */
    public PatternRide (TripPattern pattern, int fromIndex) {
        this.pattern   = pattern;
        this.fromIndex = fromIndex;
        this.toIndex = -1;
        this.stats = null;
    }

    /** Construct an unfinished PatternRide (lacking toIndex and stats) from another PatternRide. */
    public PatternRide (PatternRide other, int toIndex, Stats stats) {
        this.pattern   = other.pattern;
        this.fromIndex = other.fromIndex;
        this.toIndex = toIndex;
        this.stats = stats;
    }
    
    public Stop getFromStop() {
        return pattern.getStops().get(fromIndex);
    }
    
    public Stop getToStop() {
        return pattern.getStops().get(toIndex);            
    }
    
    public boolean finished () {
        return toIndex >= 0 && stats != null;
    }
    
    public String toString () {
        return String.format("%s %d to %d", pattern.code, fromIndex, toIndex);
    }

    /**
     * Complete an unfinished ride as a new object.
     * Perhaps we should check in advance whether a pattern is running at all, but results will vary depending on the
     * fromIndex and toIndex. Some indexes can be reached within the window, others not. But that's an optimization.
     * It's actually advantageous to call this sequentially for each to-stop instead of incrementally along a pattern.
     * This is because we store the absolute times of arrivals and departures, and by subtracting those we get accurate
     * min and max ride times rather than looser lower and upper bounds on travel time.
     */
    public PatternRide extendToIndex(int toIndex, TimeWindow window) {
        Stats stats = Stats.create (pattern, fromIndex, toIndex, window);
        /* There might not be any trips within the time window. */ 
        if (stats == null) return null;
        /* Copy most fields from this unfinished ride, setting the other fields to complete the ride. */
        PatternRide ret = new PatternRide(this, toIndex, stats);
        return ret;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy