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

org.opentripplanner.model.TripTimeOnDate Maven / Gradle / Ivy

The newest version!
package org.opentripplanner.model;

import java.time.Instant;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;
import org.opentripplanner.framework.i18n.I18NString;
import org.opentripplanner.transit.model.network.TripPattern;
import org.opentripplanner.transit.model.site.StopLocation;
import org.opentripplanner.transit.model.timetable.OccupancyStatus;
import org.opentripplanner.transit.model.timetable.RealTimeState;
import org.opentripplanner.transit.model.timetable.StopTimeKey;
import org.opentripplanner.transit.model.timetable.Trip;
import org.opentripplanner.transit.model.timetable.TripTimes;
import org.opentripplanner.transit.model.timetable.booking.BookingInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Represents a Trip at a specific stop index and on a specific service day. This is a read-only
 * data transfer object used to pass information from the OTP internal model to the APIs.
 */
public class TripTimeOnDate {

  private static final Logger LOG = LoggerFactory.getLogger(TripTimeOnDate.class);

  public static final int UNDEFINED = -1;

  private final TripTimes tripTimes;
  private final int stopIndex;
  // This is only needed because TripTimes has no reference to TripPattern
  private final TripPattern tripPattern;

  @Nullable
  private final LocalDate serviceDate;

  private final long midnight;

  public TripTimeOnDate(TripTimes tripTimes, int stopIndex, TripPattern tripPattern) {
    this.tripTimes = tripTimes;
    this.stopIndex = stopIndex;
    this.tripPattern = tripPattern;
    this.serviceDate = null;
    this.midnight = UNDEFINED;
  }

  public TripTimeOnDate(
    TripTimes tripTimes,
    int stopIndex,
    TripPattern tripPattern,
    @Nullable LocalDate serviceDate,
    @Nullable Instant midnight
  ) {
    this.tripTimes = tripTimes;
    this.stopIndex = stopIndex;
    this.tripPattern = tripPattern;
    this.serviceDate = serviceDate;
    this.midnight = midnight != null ? midnight.getEpochSecond() : UNDEFINED;
  }

  /**
   * Must pass in both Timetable and Trip, because TripTimes do not have a reference to
   * StopPatterns.
   *
   * @return null if the trip does not exist in the timetable
   */
  @Nullable
  public static List fromTripTimes(Timetable table, Trip trip) {
    TripTimes times = table.getTripTimes(trip);
    if (times == null) {
      return null;
    }
    List out = new ArrayList<>();
    for (int i = 0; i < times.getNumStops(); ++i) {
      out.add(new TripTimeOnDate(times, i, table.getPattern()));
    }
    return out;
  }

  /**
   * Must pass in both Timetable and Trip, because TripTimes do not have a reference to
   * StopPatterns.
   * 
* The timetable given must correspond to the service day so that it must contain the trip. * * @param table the timetable for the service day * @param serviceDate service day to set */ public static List fromTripTimes( Timetable table, Trip trip, LocalDate serviceDate, Instant midnight ) { // The timetable given should always contain the trip. // if the trip doesn't run on the date, the scheduled timetable should be given. TripTimes times = Objects.requireNonNull(table.getTripTimes(trip)); List out = new ArrayList<>(); for (int i = 0; i < times.getNumStops(); ++i) { out.add(new TripTimeOnDate(times, i, table.getPattern(), serviceDate, midnight)); } return out; } /** * Get first stop TripTimeOnDate from Timetable. */ public static TripTimeOnDate firstFromTripTimes( Timetable table, Trip trip, LocalDate serviceDate, Instant midnight ) { TripTimes times = table.getTripTimes(trip); return new TripTimeOnDate(times, 0, table.getPattern(), serviceDate, midnight); } /** * Get last stop TripTimeOnDate from Timetable. */ public static TripTimeOnDate lastFromTripTimes( Timetable table, Trip trip, LocalDate serviceDate, Instant midnight ) { TripTimes times = table.getTripTimes(trip); return new TripTimeOnDate( times, times.getNumStops() - 1, table.getPattern(), serviceDate, midnight ); } public static Comparator compareByDeparture() { return Comparator.comparing(t -> t.getServiceDayMidnight() + t.getRealtimeDeparture()); } public StopLocation getStop() { return tripPattern.getStop(stopIndex); } public int getStopIndex() { return stopIndex; } public TripTimes getTripTimes() { return tripTimes; } public int getStopCount() { return tripTimes.getNumStops(); } public int getScheduledArrival() { return tripTimes.getScheduledArrivalTime(stopIndex); } /** * @return The GTFS stop sequence of the stop time. */ public int getGtfsSequence() { return tripTimes.gtfsSequenceOfStopIndex(stopIndex); } public int getScheduledDeparture() { return tripTimes.getScheduledDepartureTime(stopIndex); } public int getRealtimeArrival() { return isCancelledStop() || isNoDataStop() ? tripTimes.getScheduledArrivalTime(stopIndex) : tripTimes.getArrivalTime(stopIndex); } public int getRealtimeDeparture() { return isCancelledStop() || isNoDataStop() ? tripTimes.getScheduledDepartureTime(stopIndex) : tripTimes.getDepartureTime(stopIndex); } /** * Returns the actual arrival time if available. Otherwise -1 is returned. */ public int getActualArrival() { return isRecordedStop() ? tripTimes.getArrivalTime(stopIndex) : UNDEFINED; } /** * Returns the actual departure time if available. Otherwise -1 is returned. */ public int getActualDeparture() { return isRecordedStop() ? tripTimes.getDepartureTime(stopIndex) : UNDEFINED; } public int getArrivalDelay() { return isCancelledStop() || isNoDataStop() ? 0 : tripTimes.getArrivalDelay(stopIndex); } public int getDepartureDelay() { return isCancelledStop() || isNoDataStop() ? 0 : tripTimes.getDepartureDelay(stopIndex); } public boolean isTimepoint() { return tripTimes.isTimepoint(stopIndex); } public boolean isRealtime() { return !tripTimes.isScheduled() && !isNoDataStop(); } public boolean isCancelledStop() { return ( tripTimes.isCancelledStop(stopIndex) || tripPattern.isBoardAndAlightAt(stopIndex, PickDrop.CANCELLED) ); } public boolean isPredictionInaccurate() { return tripTimes.isPredictionInaccurate(stopIndex); } /** Return {code true} if stop is cancelled, or trip is canceled/replaced */ public boolean isCanceledEffectively() { return ( isCancelledStop() || tripTimes.isCanceledOrDeleted() || tripTimes.getTrip().getNetexAlteration().isCanceledOrReplaced() ); } public boolean isNoDataStop() { return tripTimes.isNoDataStop(stopIndex); } /** * Is the real-time time a recorded time (i.e. has the vehicle already passed the stop). * This information is currently only available from SIRI feeds. */ public boolean isRecordedStop() { return tripTimes.isRecordedStop(stopIndex); } public RealTimeState getRealTimeState() { return tripTimes.isNoDataStop(stopIndex) ? RealTimeState.SCHEDULED : tripTimes.getRealTimeState(); } public OccupancyStatus getOccupancyStatus() { return tripTimes.getOccupancyStatus(stopIndex); } public long getServiceDayMidnight() { return midnight; } public LocalDate getServiceDay() { return serviceDate; } public Trip getTrip() { return tripTimes.getTrip(); } public String getBlockId() { return tripTimes.getTrip().getGtfsBlockId(); } public I18NString getHeadsign() { return tripTimes.getHeadsign(stopIndex); } /** @return a list of via names visible at this stop, or an empty list if there are no vias. */ public List getHeadsignVias() { return tripTimes.getHeadsignVias(stopIndex); } public PickDrop getPickupType() { if (tripTimes.isDeleted()) { LOG.warn( "Returning pickup type for a deleted trip {} on pattern {} on date {}. This indicates a bug.", tripTimes.getTrip().getId(), tripPattern.getId(), serviceDate ); return tripPattern.getBoardType(stopIndex); } return tripTimes.isCanceled() || tripTimes.isCancelledStop(stopIndex) ? PickDrop.CANCELLED : tripPattern.getBoardType(stopIndex); } public PickDrop getDropoffType() { if (tripTimes.isDeleted()) { LOG.warn( "Returning dropoff type for a deleted trip {} on pattern {} on date {}. This indicates a bug.", tripTimes.getTrip().getId(), tripPattern.getId(), serviceDate ); return tripPattern.getAlightType(stopIndex); } return tripTimes.isCanceled() || tripTimes.isCancelledStop(stopIndex) ? PickDrop.CANCELLED : tripPattern.getAlightType(stopIndex); } public StopTimeKey getStopTimeKey() { return StopTimeKey.of(tripTimes.getTrip().getId(), stopIndex).build(); } public BookingInfo getPickupBookingInfo() { return tripTimes.getPickupBookingInfo(stopIndex); } public BookingInfo getDropOffBookingInfo() { return tripTimes.getDropOffBookingInfo(stopIndex); } @Override public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; TripTimeOnDate that = (TripTimeOnDate) o; return ( stopIndex == that.stopIndex && midnight == that.midnight && Objects.equals(tripTimes, that.tripTimes) && Objects.equals(tripPattern, that.tripPattern) && Objects.equals(serviceDate, that.serviceDate) ); } @Override public int hashCode() { return Objects.hash(tripTimes, stopIndex, tripPattern, serviceDate, midnight); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy