Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/fix-departureArrivalStopTime-npe…
Browse files Browse the repository at this point in the history
…' into fix-update-stale-service

# Conflicts:
#	application/src/test/java/org/opentripplanner/transit/service/DefaultTransitServiceTest.java
  • Loading branch information
miklcct committed Nov 26, 2024
2 parents 3a4753e + a7dc78e commit c2bc785
Show file tree
Hide file tree
Showing 14 changed files with 597 additions and 204 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import java.text.ParseException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
Expand All @@ -13,6 +12,7 @@
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.LineString;
import org.opentripplanner.apis.gtfs.GraphQLRequestContext;
Expand All @@ -23,7 +23,6 @@
import org.opentripplanner.apis.gtfs.mapping.BikesAllowedMapper;
import org.opentripplanner.apis.gtfs.model.TripOccupancy;
import org.opentripplanner.apis.support.SemanticHash;
import org.opentripplanner.model.Timetable;
import org.opentripplanner.model.TripTimeOnDate;
import org.opentripplanner.routing.alertpatch.EntitySelector;
import org.opentripplanner.routing.alertpatch.TransitAlert;
Expand All @@ -36,7 +35,6 @@
import org.opentripplanner.transit.model.site.StopLocation;
import org.opentripplanner.transit.model.timetable.Direction;
import org.opentripplanner.transit.model.timetable.Trip;
import org.opentripplanner.transit.model.timetable.TripTimes;
import org.opentripplanner.transit.service.TransitService;
import org.opentripplanner.utils.time.ServiceDateUtils;

Expand Down Expand Up @@ -132,38 +130,13 @@ public DataFetcher<Iterable<TransitAlert>> alerts() {
@Override
public DataFetcher<TripTimeOnDate> arrivalStoptime() {
return environment -> {
try {
TransitService transitService = getTransitService(environment);
TripPattern tripPattern = getTripPattern(environment);
if (tripPattern == null) {
return null;
}
Timetable timetable = tripPattern.getScheduledTimetable();

TripTimes triptimes = timetable.getTripTimes(getSource(environment));
LocalDate serviceDate = null;
Instant midnight = null;

var args = new GraphQLTypes.GraphQLTripArrivalStoptimeArgs(environment.getArguments());
if (args.getGraphQLServiceDate() != null) {
serviceDate = ServiceDateUtils.parseString(args.getGraphQLServiceDate());
midnight =
ServiceDateUtils
.asStartOfService(serviceDate, transitService.getTimeZone())
.toInstant();
}

return new TripTimeOnDate(
triptimes,
triptimes.getNumStops() - 1,
tripPattern,
serviceDate,
midnight
);
} catch (ParseException e) {
//Invalid date format
return null;
}
var serviceDate = getOptionalServiceDateArgument(environment);
var trip = getSource(environment);
var transitService = getTransitService(environment);
var stopTimes = serviceDate
.map(date -> transitService.getTripTimeOnDates(trip, date))
.orElseGet(() -> transitService.getScheduledTripTimes(trip));
return stopTimes.map(List::getLast).orElse(null);
};
}

Expand All @@ -180,32 +153,13 @@ public DataFetcher<String> blockId() {
@Override
public DataFetcher<TripTimeOnDate> departureStoptime() {
return environment -> {
try {
TransitService transitService = getTransitService(environment);
TripPattern tripPattern = getTripPattern(environment);
if (tripPattern == null) {
return null;
}
Timetable timetable = tripPattern.getScheduledTimetable();

TripTimes triptimes = timetable.getTripTimes(getSource(environment));
LocalDate serviceDate = null;
Instant midnight = null;

var args = new GraphQLTypes.GraphQLTripDepartureStoptimeArgs(environment.getArguments());
if (args.getGraphQLServiceDate() != null) {
serviceDate = ServiceDateUtils.parseString(args.getGraphQLServiceDate());
midnight =
ServiceDateUtils
.asStartOfService(serviceDate, transitService.getTimeZone())
.toInstant();
}

return new TripTimeOnDate(triptimes, 0, tripPattern, serviceDate, midnight);
} catch (ParseException e) {
//Invalid date format
return null;
}
var serviceDate = getOptionalServiceDateArgument(environment);
var trip = getSource(environment);
var transitService = getTransitService(environment);
var stopTimes = serviceDate
.map(date -> transitService.getTripTimeOnDates(trip, date))
.orElseGet(() -> transitService.getScheduledTripTimes(trip));
return stopTimes.map(List::getFirst).orElse(null);
};
}

Expand Down Expand Up @@ -300,43 +254,23 @@ public DataFetcher<Iterable<Object>> stops() {

@Override
public DataFetcher<Iterable<TripTimeOnDate>> stoptimes() {
return environment -> {
TripPattern tripPattern = getTripPattern(environment);
if (tripPattern == null) {
return List.of();
}
return TripTimeOnDate.fromTripTimes(
tripPattern.getScheduledTimetable(),
getSource(environment)
);
};
return environment ->
getTransitService(environment).getScheduledTripTimes(getSource(environment)).orElse(null);
}

@Override
public DataFetcher<Iterable<TripTimeOnDate>> stoptimesForDate() {
return environment -> {
try {
TransitService transitService = getTransitService(environment);
Trip trip = getSource(environment);
var args = new GraphQLTypes.GraphQLTripStoptimesForDateArgs(environment.getArguments());

ZoneId timeZone = transitService.getTimeZone();
LocalDate serviceDate = args.getGraphQLServiceDate() != null
? ServiceDateUtils.parseString(args.getGraphQLServiceDate())
: LocalDate.now(timeZone);

TripPattern tripPattern = transitService.getPatternForTrip(trip, serviceDate);
// no matching pattern found
if (tripPattern == null) {
return List.of();
}

Instant midnight = ServiceDateUtils.asStartOfService(serviceDate, timeZone).toInstant();
Timetable timetable = transitService.getTimetableForTripPattern(tripPattern, serviceDate);
return TripTimeOnDate.fromTripTimes(timetable, trip, serviceDate, midnight);
} catch (ParseException e) {
return null; // Invalid date format
}
TransitService transitService = getTransitService(environment);
Trip trip = getSource(environment);
var args = new GraphQLTypes.GraphQLTripStoptimesForDateArgs(environment.getArguments());

ZoneId timeZone = transitService.getTimeZone();
LocalDate serviceDate = args.getGraphQLServiceDate() != null
? ServiceDateUtils.parseString(args.getGraphQLServiceDate())
: LocalDate.now(timeZone);

return transitService.getTripTimeOnDates(trip, serviceDate).orElse(null);
};
}

Expand Down Expand Up @@ -400,6 +334,15 @@ private TripPattern getTripPattern(DataFetchingEnvironment environment) {
return getTransitService(environment).getPatternForTrip(environment.getSource());
}

private TripPattern getTripPattern(
DataFetchingEnvironment environment,
@Nullable LocalDate date
) {
return date == null
? getTripPattern(environment)
: getTransitService(environment).getPatternForTrip(environment.getSource(), date);
}

private TransitService getTransitService(DataFetchingEnvironment environment) {
return environment.<GraphQLRequestContext>getContext().transitService();
}
Expand All @@ -408,6 +351,16 @@ private RealtimeVehicleService getRealtimeVehiclesService(DataFetchingEnvironmen
return environment.<GraphQLRequestContext>getContext().realTimeVehicleService();
}

private static Optional<LocalDate> getOptionalServiceDateArgument(
DataFetchingEnvironment environment
) throws ParseException {
var args = new GraphQLTypes.GraphQLTripArrivalStoptimeArgs(environment.getArguments());
if (args.getGraphQLServiceDate() != null) {
return Optional.of(ServiceDateUtils.parseString(args.getGraphQLServiceDate()));
}
return Optional.empty();
}

private Trip getSource(DataFetchingEnvironment environment) {
return environment.getSource();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import org.opentripplanner.apis.transmodel.model.framework.TransmodelDirectives;
import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars;
import org.opentripplanner.apis.transmodel.support.GqlUtil;
import org.opentripplanner.routing.TripTimeOnDateHelper;
import org.opentripplanner.transit.model.network.TripPattern;
import org.opentripplanner.transit.model.site.StopLocation;
import org.opentripplanner.transit.model.timetable.TripOnServiceDate;
Expand Down Expand Up @@ -152,11 +151,10 @@ public static GraphQLObjectType create(
)
.dataFetcher(environment -> {
TripOnServiceDate tripOnServiceDate = tripOnServiceDate(environment);
return TripTimeOnDateHelper.getTripTimeOnDates(
GqlUtil.getTransitService(environment),
tripOnServiceDate.getTrip(),
tripOnServiceDate.getServiceDate()
);
return GqlUtil
.getTransitService(environment)
.getTripTimeOnDates(tripOnServiceDate.getTrip(), tripOnServiceDate.getServiceDate())
.orElse(null);
})
.build()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import org.opentripplanner.apis.transmodel.model.framework.TransmodelScalars;
import org.opentripplanner.apis.transmodel.support.GqlUtil;
import org.opentripplanner.framework.geometry.EncodedPolyline;
import org.opentripplanner.model.TripTimeOnDate;
import org.opentripplanner.routing.TripTimeOnDateHelper;
import org.opentripplanner.transit.model.network.TripPattern;
import org.opentripplanner.transit.model.site.StopLocation;
import org.opentripplanner.transit.model.timetable.Trip;
Expand Down Expand Up @@ -235,14 +233,7 @@ public static GraphQLObjectType create(
.description(
"Returns scheduled passing times only - without real-time-updates, for realtime-data use 'estimatedCalls'"
)
.dataFetcher(env -> {
Trip trip = trip(env);
TripPattern tripPattern = GqlUtil.getTransitService(env).getPatternForTrip(trip);
if (tripPattern == null) {
return List.of();
}
return TripTimeOnDate.fromTripTimes(tripPattern.getScheduledTimetable(), trip);
})
.dataFetcher(env -> GqlUtil.getTransitService(env).getScheduledTripTimes(trip(env)))
.build()
)
.field(
Expand All @@ -269,11 +260,10 @@ public static GraphQLObjectType create(
.ofNullable(environment.getArgument("date"))
.map(LocalDate.class::cast)
.orElse(LocalDate.now(GqlUtil.getTransitService(environment).getTimeZone()));
return TripTimeOnDateHelper.getTripTimeOnDates(
GqlUtil.getTransitService(environment),
trip(environment),
serviceDate
);
return GqlUtil
.getTransitService(environment)
.getTripTimeOnDates(trip(environment), serviceDate)
.orElse(null);
})
.build()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
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;
Expand All @@ -31,7 +33,10 @@ public class TripTimeOnDate {
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) {
Expand All @@ -46,8 +51,8 @@ public TripTimeOnDate(
TripTimes tripTimes,
int stopIndex,
TripPattern tripPattern,
LocalDate serviceDate,
Instant midnight
@Nullable LocalDate serviceDate,
@Nullable Instant midnight
) {
this.tripTimes = tripTimes;
this.stopIndex = stopIndex;
Expand All @@ -59,9 +64,15 @@ public TripTimeOnDate(
/**
* 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<TripTimeOnDate> fromTripTimes(Timetable table, Trip trip) {
TripTimes times = table.getTripTimes(trip);
if (times == null) {
return null;
}
List<TripTimeOnDate> out = new ArrayList<>();
for (int i = 0; i < times.getNumStops(); ++i) {
out.add(new TripTimeOnDate(times, i, table.getPattern()));
Expand All @@ -74,14 +85,20 @@ public static List<TripTimeOnDate> fromTripTimes(Timetable table, Trip trip) {
* StopPatterns.
*
* @param serviceDate service day to set, if null none is set
* @return null if the trip does not exist in the timetable
*/

@Nullable
public static List<TripTimeOnDate> fromTripTimes(
Timetable table,
Trip trip,
LocalDate serviceDate,
Instant midnight
) {
TripTimes times = table.getTripTimes(trip);
if (times == null) {
return null;
}
List<TripTimeOnDate> out = new ArrayList<>();
for (int i = 0; i < times.getNumStops(); ++i) {
out.add(new TripTimeOnDate(times, i, table.getPattern(), serviceDate, midnight));
Expand Down Expand Up @@ -270,4 +287,22 @@ public BookingInfo getPickupBookingInfo() {
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);
}
}
Loading

0 comments on commit c2bc785

Please sign in to comment.