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

org.opentripplanner.transit.model.timetable.Trip Maven / Gradle / Ivy

/* This file is based on code copied from project OneBusAway, see the LICENSE file for further information. */
package org.opentripplanner.transit.model.timetable;

import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNullElse;
import static org.opentripplanner.util.lang.ObjectUtils.ifNotNull;

import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opentripplanner.transit.model.basic.Accessibility;
import org.opentripplanner.transit.model.basic.I18NString;
import org.opentripplanner.transit.model.basic.SubMode;
import org.opentripplanner.transit.model.basic.TransitMode;
import org.opentripplanner.transit.model.framework.AbstractTransitEntity;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.model.framework.LogInfo;
import org.opentripplanner.transit.model.network.BikeAccess;
import org.opentripplanner.transit.model.network.Route;
import org.opentripplanner.transit.model.organization.Operator;
import org.opentripplanner.util.lang.StringUtils;

public final class Trip extends AbstractTransitEntity implements LogInfo {

  private final Operator operator;
  private final Route route;
  private final FeedScopedId serviceId;
  private final String shortName;
  private final TransitMode mode;
  private final SubMode netexSubmode;
  private final I18NString headsign;
  private final FeedScopedId shapeId;

  private final Direction direction;
  private final BikeAccess bikesAllowed;
  private final Accessibility wheelchairBoarding;

  private final String gtfsBlockId;
  private final String gtfsFareId;

  private final String netexInternalPlanningCode;
  private final TripAlteration netexAlteration;

  Trip(TripBuilder builder) {
    super(builder.getId());
    // Required fields
    // Route is done first, it is used as a fallback for some fields
    this.route = requireNonNull(builder.getRoute());
    this.mode = requireNonNullElse(builder.getMode(), route.getMode());
    this.netexSubmode =
      builder.getNetexSubmode() != null
        ? SubMode.getOrBuildAndCacheForever(builder.getNetexSubmode())
        : route.getNetexSubmode();
    this.direction = requireNonNullElse(builder.getDirection(), Direction.UNKNOWN);
    this.bikesAllowed = requireNonNullElse(builder.getBikesAllowed(), route.getBikesAllowed());
    this.wheelchairBoarding =
      requireNonNullElse(builder.getWheelchairBoarding(), Accessibility.NO_INFORMATION);
    this.netexAlteration = requireNonNullElse(builder.getNetexAlteration(), TripAlteration.PLANNED);

    // Optional fields

    this.operator = ifNotNull(builder.getOperator(), route.getOperator());
    this.serviceId = builder.getServiceId();
    this.shortName = builder.getShortName();
    this.headsign = builder.getHeadsign();
    this.shapeId = builder.getShapeId();
    this.gtfsBlockId = builder.getGtfsBlockId();
    this.gtfsFareId = builder.getGtfsFareId();
    this.netexInternalPlanningCode = builder.getNetexInternalPlanningCode();
  }

  public static TripBuilder of(@Nonnull FeedScopedId id) {
    return new TripBuilder(id);
  }

  /**
   * Operator running the trip. Returns operator of this trip, if it exist, or else the route
   * operator.
   */
  @Nullable
  public Operator getOperator() {
    return operator;
  }

  @Nonnull
  public Route getRoute() {
    return route;
  }

  /**
   * At the moment this is probably null-safe, but we want to reduce this to GTFS serviceId for
   * matching trips in GTFS RT updates, if the datasource is NeTEx, then we do not have this and
   * would like to remove todays generated ID.
   */
  @Nullable
  public FeedScopedId getServiceId() {
    return serviceId;
  }

  /**
   * Public code or identifier for the journey. Equal to NeTEx PublicCode. GTFS and NeTEx have
   * additional constraints on this fields that are not enforced in OTP.
   */
  @Nullable
  public String getShortName() {
    return shortName;
  }

  @Nonnull
  public TransitMode getMode() {
    return mode;
  }

  @Nonnull
  public SubMode getNetexSubMode() {
    return netexSubmode;
  }

  @Nullable
  public I18NString getHeadsign() {
    return headsign;
  }

  @Nullable
  public FeedScopedId getShapeId() {
    return shapeId;
  }

  /**
   * The direction for this Trip (and all other Trips in this TripPattern).
   */
  @Nonnull
  public Direction getDirection() {
    return direction;
  }

  @Nonnull
  public BikeAccess getBikesAllowed() {
    return bikesAllowed;
  }

  @Nonnull
  public Accessibility getWheelchairBoarding() {
    return wheelchairBoarding;
  }

  @Nullable
  public String getGtfsBlockId() {
    return gtfsBlockId;
  }

  /** Custom extension for KCM to specify a fare per-trip */
  @Nullable
  public String getGtfsFareId() {
    return gtfsFareId;
  }

  /**
   * Internal code (non-public identifier) for the journey (e.g. train- or trip number from the
   * planners' tool). This is kept to ensure compatibility with legacy planning systems. In NeTEx
   * this maps to privateCode, there is no GTFS equivalent.
   */
  @Nullable
  public String getNetexInternalPlanningCode() {
    return netexInternalPlanningCode;
  }

  /**
   * Default alteration for a trip.
   * 

* This is planned, by default (e.g. GTFS and if not set explicit). */ @Nonnull public TripAlteration getNetexAlteration() { return netexAlteration; } /** * Return human friendly name to identify the trip when mode, from/to stop and times are * known. This method is meant for debug/logging, and should not be exposed in any API. */ public String logName() { if (StringUtils.hasValue(shortName)) { return shortName; } if (StringUtils.hasValue(route.getName())) { return route.getName(); } if (I18NString.hasValue(headsign)) { return headsign.toString(); } return mode.name(); } @Override public boolean sameAs(@Nonnull Trip other) { return ( getId().equals(other.getId()) && Objects.equals(this.operator, other.operator) && Objects.equals(this.route, other.route) && Objects.equals(this.shortName, other.shortName) && Objects.equals(this.mode, other.mode) && Objects.equals(this.netexSubmode, other.netexSubmode) && Objects.equals(this.serviceId, other.serviceId) && Objects.equals(this.netexInternalPlanningCode, other.netexInternalPlanningCode) && Objects.equals(this.headsign, other.headsign) && Objects.equals(this.gtfsBlockId, other.gtfsBlockId) && Objects.equals(this.shapeId, other.shapeId) && Objects.equals(this.direction, other.direction) && Objects.equals(this.bikesAllowed, other.bikesAllowed) && Objects.equals(this.wheelchairBoarding, other.wheelchairBoarding) && Objects.equals(this.netexAlteration, other.netexAlteration) && Objects.equals(this.gtfsFareId, other.gtfsFareId) ); } @Override public TripBuilder copy() { return new TripBuilder(this); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy