Skip to content

Commit

Permalink
Create DatedStopTime type and use it in DatedTrip
Browse files Browse the repository at this point in the history
  • Loading branch information
optionsome committed Aug 9, 2024
1 parent b142bdf commit 8e12d3a
Show file tree
Hide file tree
Showing 11 changed files with 311 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.opentripplanner.apis.gtfs.datafetchers.ContactInfoImpl;
import org.opentripplanner.apis.gtfs.datafetchers.CoordinatesImpl;
import org.opentripplanner.apis.gtfs.datafetchers.CurrencyImpl;
import org.opentripplanner.apis.gtfs.datafetchers.DatedStopTimeImpl;
import org.opentripplanner.apis.gtfs.datafetchers.DatedTripImpl;
import org.opentripplanner.apis.gtfs.datafetchers.DefaultFareProductImpl;
import org.opentripplanner.apis.gtfs.datafetchers.DepartureRowImpl;
Expand Down Expand Up @@ -180,6 +181,7 @@ protected static GraphQLSchema buildSchema() {
.type(typeWiring.build(FareProductUseImpl.class))
.type(typeWiring.build(DefaultFareProductImpl.class))
.type(typeWiring.build(DatedTripImpl.class))
.type(typeWiring.build(DatedStopTimeImpl.class))
.type(typeWiring.build(TripOccupancyImpl.class))
.build();
SchemaGenerator schemaGenerator = new SchemaGenerator();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package org.opentripplanner.apis.gtfs.datafetchers;

import static org.opentripplanner.apis.gtfs.GraphQLUtils.stopTimeToInt;

import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import java.time.ZonedDateTime;
import org.opentripplanner.apis.gtfs.GraphQLRequestContext;
import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers;
import org.opentripplanner.apis.gtfs.generated.GraphQLTypes;
import org.opentripplanner.apis.gtfs.mapping.PickDropMapper;
import org.opentripplanner.apis.gtfs.model.ArrivalDepartureTime;
import org.opentripplanner.framework.graphql.GraphQLUtils;
import org.opentripplanner.framework.time.ServiceDateUtils;
import org.opentripplanner.model.TripTimeOnDate;
import org.opentripplanner.transit.service.TransitService;

public class DatedStopTimeImpl implements GraphQLDataFetchers.GraphQLDatedStopTime {

@Override
public DataFetcher<ArrivalDepartureTime> arrival() {
return environment -> {
var tripTime = getSource(environment);
var scheduledTime = getZonedDateTime(environment, tripTime.getScheduledArrival());
if (scheduledTime == null) {
return null;
}
return tripTime.isRealtime()
? ArrivalDepartureTime.of(scheduledTime, tripTime.getArrivalDelay())
: ArrivalDepartureTime.ofStatic(scheduledTime);
};
}

@Override
public DataFetcher<ArrivalDepartureTime> departure() {
return environment -> {
var tripTime = getSource(environment);
var scheduledTime = getZonedDateTime(environment, tripTime.getScheduledDeparture());
if (scheduledTime == null) {
return null;
}
return tripTime.isRealtime()
? ArrivalDepartureTime.of(scheduledTime, tripTime.getDepartureDelay())
: ArrivalDepartureTime.ofStatic(scheduledTime);
};
}

@Override
public DataFetcher<String> dropoffType() {
return environment -> PickDropMapper.map(getSource(environment).getDropoffType());
}

@Override
public DataFetcher<String> headsign() {
return environment ->
GraphQLUtils.getTranslation(getSource(environment).getHeadsign(), environment);
}

@Override
public DataFetcher<String> pickupType() {
return environment -> PickDropMapper.map(getSource(environment).getPickupType());
}

@Override
public DataFetcher<GraphQLTypes.GraphQLStopRealTimeState> realtimeState() {
return environment -> {
var tripTime = getSource(environment);
// TODO support ADDED state
if (tripTime.isCanceledEffectively()) {
return GraphQLTypes.GraphQLStopRealTimeState.CANCELED;
}
if (tripTime.isNoDataStop()) {
return GraphQLTypes.GraphQLStopRealTimeState.NO_DATA;
}
if (tripTime.isRecordedStop()) {
return GraphQLTypes.GraphQLStopRealTimeState.RECORDED;
}
if (tripTime.isRealtime()) {
return GraphQLTypes.GraphQLStopRealTimeState.UPDATED;
}
return GraphQLTypes.GraphQLStopRealTimeState.UNUPDATED;
};
}

@Override
public DataFetcher<Integer> stopPosition() {
return environment -> getSource(environment).getGtfsSequence();
}

@Override
public DataFetcher<Object> stop() {
return environment -> getSource(environment).getStop();
}

@Override
public DataFetcher<Boolean> timepoint() {
return environment -> getSource(environment).isTimepoint();
}

private TransitService getTransitService(DataFetchingEnvironment environment) {
return environment.<GraphQLRequestContext>getContext().transitService();
}

private ZonedDateTime getZonedDateTime(DataFetchingEnvironment environment, int time) {
var fixedTime = stopTimeToInt(time);
if (fixedTime == null) {
return null;
}
var serviceDate = getSource(environment).getServiceDay();
TransitService transitService = getTransitService(environment);
return ServiceDateUtils.toZonedDateTime(serviceDate, transitService.getTimeZone(), fixedTime);
}

private TripTimeOnDate getSource(DataFetchingEnvironment environment) {
return environment.getSource();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import javax.annotation.Nullable;
import org.opentripplanner.apis.gtfs.GraphQLRequestContext;
import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers;
import org.opentripplanner.apis.gtfs.model.DatedTripTime;
import org.opentripplanner.apis.gtfs.model.ArrivalDepartureTime;
import org.opentripplanner.ext.restapi.mapping.LocalDateMapper;
import org.opentripplanner.framework.time.ServiceDateUtils;
import org.opentripplanner.model.Timetable;
Expand All @@ -32,7 +32,7 @@ public DataFetcher<LocalDate> date() {
}

@Override
public DataFetcher<DatedTripTime> end() {
public DataFetcher<ArrivalDepartureTime> end() {
return env -> {
var tripTimes = getTripTimes(env);
if (tripTimes == null) {
Expand All @@ -44,8 +44,8 @@ public DataFetcher<DatedTripTime> end() {
return null;
}
return tripTimes.isRealtimeUpdated(stopIndex)
? DatedTripTime.of(scheduledTime, tripTimes.getArrivalDelay(stopIndex))
: DatedTripTime.ofStatic(scheduledTime);
? ArrivalDepartureTime.of(scheduledTime, tripTimes.getArrivalDelay(stopIndex))
: ArrivalDepartureTime.ofStatic(scheduledTime);
};
}

Expand All @@ -71,7 +71,7 @@ public DataFetcher<Route> route() {
}

@Override
public DataFetcher<DatedTripTime> start() {
public DataFetcher<ArrivalDepartureTime> start() {
return env -> {
var tripTimes = getTripTimes(env);
if (tripTimes == null) {
Expand All @@ -82,8 +82,8 @@ public DataFetcher<DatedTripTime> start() {
return null;
}
return tripTimes.isRealtimeUpdated(0)
? DatedTripTime.of(scheduledTime, tripTimes.getDepartureDelay(0))
: DatedTripTime.ofStatic(scheduledTime);
? ArrivalDepartureTime.of(scheduledTime, tripTimes.getDepartureDelay(0))
: ArrivalDepartureTime.ofStatic(scheduledTime);
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers;
import org.opentripplanner.apis.gtfs.mapping.PickDropMapper;
import org.opentripplanner.framework.graphql.GraphQLUtils;
import org.opentripplanner.model.TripTimeOnDate;
import org.opentripplanner.transit.model.timetable.RealTimeState;
Expand All @@ -24,14 +25,7 @@ public DataFetcher<Integer> departureDelay() {

@Override
public DataFetcher<String> dropoffType() {
return environment ->
switch (getSource(environment).getDropoffType()) {
case SCHEDULED -> "SCHEDULED";
case NONE -> "NONE";
case CALL_AGENCY -> "CALL_AGENCY";
case COORDINATE_WITH_DRIVER -> "COORDINATE_WITH_DRIVER";
case CANCELLED -> null;
};
return environment -> PickDropMapper.map(getSource(environment).getDropoffType());
}

@Override
Expand All @@ -42,14 +36,7 @@ public DataFetcher<String> headsign() {

@Override
public DataFetcher<String> pickupType() {
return environment ->
switch (getSource(environment).getPickupType()) {
case SCHEDULED -> "SCHEDULED";
case NONE -> "NONE";
case CALL_AGENCY -> "CALL_AGENCY";
case COORDINATE_WITH_DRIVER -> "COORDINATE_WITH_DRIVER";
case CANCELLED -> null;
};
return environment -> PickDropMapper.map(getSource(environment).getPickupType());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLOccupancyStatus;
import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLRelativeDirection;
import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLRoutingErrorCode;
import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLStopRealTimeState;
import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLTransitMode;
import org.opentripplanner.apis.gtfs.model.DatedTripTime;
import org.opentripplanner.apis.gtfs.model.ArrivalDepartureTime;
import org.opentripplanner.apis.gtfs.model.FeedPublisher;
import org.opentripplanner.apis.gtfs.model.PlanPageInfo;
import org.opentripplanner.apis.gtfs.model.RideHailingProvider;
Expand Down Expand Up @@ -141,6 +142,16 @@ public interface GraphQLAlert {
/** Entity related to an alert */
public interface GraphQLAlertEntity extends TypeResolver {}

/**
* Timing of an arrival or a departure to or from a stop. May contain real-time information if
* available.
*/
public interface GraphQLArrivalDepartureTime {
public DataFetcher<Object> estimated();

public DataFetcher<java.time.OffsetDateTime> scheduledTime();
}

/** Bike park represents a location where bicycles can be parked. */
public interface GraphQLBikePark {
public DataFetcher<String> bikeParkId();
Expand Down Expand Up @@ -316,19 +327,40 @@ public interface GraphQLCurrency {
public DataFetcher<Integer> digits();
}

/** Stoptime represents the time when a specific trip on a specific date arrives to and/or departs from a specific stop. */
public interface GraphQLDatedStopTime {
public DataFetcher<ArrivalDepartureTime> arrival();

public DataFetcher<ArrivalDepartureTime> departure();

public DataFetcher<String> dropoffType();

public DataFetcher<String> headsign();

public DataFetcher<String> pickupType();

public DataFetcher<GraphQLStopRealTimeState> realtimeState();

public DataFetcher<Object> stop();

public DataFetcher<Integer> stopPosition();

public DataFetcher<Boolean> timepoint();
}

/** Trip on a specific date */
public interface GraphQLDatedTrip {
public DataFetcher<java.time.LocalDate> date();

public DataFetcher<DatedTripTime> end();
public DataFetcher<ArrivalDepartureTime> end();

public DataFetcher<graphql.relay.Relay.ResolvedGlobalId> id();

public DataFetcher<TripPattern> pattern();

public DataFetcher<Route> route();

public DataFetcher<DatedTripTime> start();
public DataFetcher<ArrivalDepartureTime> start();

public DataFetcher<Iterable<Object>> stops();

Expand Down Expand Up @@ -359,16 +391,6 @@ public interface GraphQLDatedTripEdge {
public DataFetcher<DatedTrip> node();
}

/**
* Information about a dated trip's start or end times. May contain real-time information if
* available.
*/
public interface GraphQLDatedTripTime {
public DataFetcher<Object> estimated();

public DataFetcher<java.time.OffsetDateTime> scheduledTime();
}

/**
* The standard case of a fare product: it only has a single price to be paid by the passenger
* and no discounts are applied.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,25 @@ public enum GraphQLCyclingOptimizationType {
SHORTEST_DURATION,
}

public static class GraphQLDatedStopTimeHeadsignArgs {

private String language;

public GraphQLDatedStopTimeHeadsignArgs(Map<String, Object> args) {
if (args != null) {
this.language = (String) args.get("language");
}
}

public String getGraphQLLanguage() {
return this.language;
}

public void setGraphQLLanguage(String language) {
this.language = language;
}
}

public static class GraphQLDatedTripTripHeadsignArgs {

private String language;
Expand Down Expand Up @@ -4584,6 +4603,16 @@ public enum GraphQLStopAlertType {
TRIPS,
}

/** Whether stop has been updated through a realtime update and if so, how. */
public enum GraphQLStopRealTimeState {
ADDED,
CANCELED,
NO_DATA,
RECORDED,
UNUPDATED,
UPDATED,
}

public static class GraphQLStoptimeHeadsignArgs {

private String language;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,11 @@ config:
ContactInfo: org.opentripplanner.transit.model.organization.ContactInfo
Cluster: Object
Coordinates: org.locationtech.jts.geom.Coordinate#Coordinate
DatedStopTime: org.opentripplanner.model.TripTimeOnDate#TripTimeOnDate
DatedTrip: org.opentripplanner.transit.model.timetable.DatedTrip#DatedTrip
DatedTripConnection: graphql.relay.Connection#Connection<DatedTrip>
DatedTripEdge: graphql.relay.Edge#Edge<DatedTrip>
DatedTripTime: org.opentripplanner.apis.gtfs.model.DatedTripTime#DatedTripTime
ArrivalDepartureTime: org.opentripplanner.apis.gtfs.model.ArrivalDepartureTime#ArrivalDepartureTime
debugOutput: org.opentripplanner.api.resource.DebugOutput#DebugOutput
DepartureRow: org.opentripplanner.routing.graphfinder.PatternAtStop#PatternAtStop
elevationProfileComponent: org.opentripplanner.model.plan.ElevationProfile.Step
Expand Down Expand Up @@ -101,6 +102,7 @@ config:
stopAtDistanceEdge: graphql.relay.Edge#Edge<NearbyStop>
StopOnRoute: org.opentripplanner.apis.gtfs.model.StopOnRouteModel#StopOnRouteModel
StopOnTrip: org.opentripplanner.apis.gtfs.model.StopOnTripModel#StopOnTripModel
StopRealTimeState: org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLStopRealTimeState#GraphQLStopRealTimeState
Stoptime: org.opentripplanner.model.TripTimeOnDate#TripTimeOnDate
StoptimesInPattern: org.opentripplanner.model.StopTimesInPattern#StopTimesInPattern
TicketType: org.opentripplanner.ext.fares.model.FareRuleSet#FareRuleSet
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.opentripplanner.apis.gtfs.mapping;

import javax.annotation.Nullable;
import org.opentripplanner.model.PickDrop;

public final class PickDropMapper {

@Nullable
public static String map(PickDrop pickDrop) {
return switch (pickDrop) {
case SCHEDULED -> "SCHEDULED";
case NONE -> "NONE";
case CALL_AGENCY -> "CALL_AGENCY";
case COORDINATE_WITH_DRIVER -> "COORDINATE_WITH_DRIVER";
case CANCELLED -> null;
};
}
}
Loading

0 comments on commit 8e12d3a

Please sign in to comment.