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

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

The newest version!
/* 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.utils.lang.ObjectUtils.ifNotNull;

import java.util.Objects;
import javax.annotation.Nullable;
import org.opentripplanner.framework.i18n.I18NString;
import org.opentripplanner.transit.model.basic.Accessibility;
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.CarAccess;
import org.opentripplanner.transit.model.network.Route;
import org.opentripplanner.transit.model.organization.Operator;
import org.opentripplanner.utils.lang.StringUtils;

/**
 * A Trip represents the movement of a public transport vehicle on a given {@link Route}, using a
 * given {@link TransitMode}, on a given sequence of stops served at given passing times.
 * 

A scheduled Trip can run at most once per service date, * while a frequency-based Trip runs several times on a given service date. *

A Trip can run on multiple service dates. *

The service dates on which a trip is running are identified * by its service id and can be looked up with * {@link org.opentripplanner.model.calendar.CalendarService}. *

Trips that follow the same sequence of stops are grouped under a {@link org.opentripplanner.transit.model.network.TripPattern} * via a {@link org.opentripplanner.model.Timetable} *

A Trip is equivalent to the TransModel concept of SERVICE JOURNEY. */ public final class Trip extends AbstractTransitEntity implements LogInfo { private final Route route; private final TransitMode mode; private final Direction direction; private final BikeAccess bikesAllowed; private final CarAccess carsAllowed; private final Accessibility wheelchairBoarding; private final SubMode netexSubmode; private final TripAlteration netexAlteration; @Nullable private final Operator operator; @Nullable private final FeedScopedId serviceId; @Nullable private final String shortName; @Nullable private final I18NString headsign; @Nullable private final FeedScopedId shapeId; @Nullable private final String gtfsBlockId; @Nullable private final String netexInternalPlanningCode; 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.carsAllowed = requireNonNullElse(builder.getCarsAllowed(), CarAccess.UNKNOWN); 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.netexInternalPlanningCode = builder.getNetexInternalPlanningCode(); } public static TripBuilder of(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; } 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; } public TransitMode getMode() { return mode; } 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). */ public Direction getDirection() { return direction; } public BikeAccess getBikesAllowed() { return bikesAllowed; } public CarAccess getCarsAllowed() { return carsAllowed; } public Accessibility getWheelchairBoarding() { return wheelchairBoarding; } @Nullable public String getGtfsBlockId() { return gtfsBlockId; } /** * 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). */ 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(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.carsAllowed, other.carsAllowed) && Objects.equals(this.wheelchairBoarding, other.wheelchairBoarding) && Objects.equals(this.netexAlteration, other.netexAlteration) ); } @Override public TripBuilder copy() { return new TripBuilder(this); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy