Skip to content

Add a "canceled" field to Place in GTFS GraphQL API #6445

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: dev-2.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,14 @@ public DataFetcher<Iterable<FareProductUse>> fareProducts() {
public DataFetcher<StopArrival> from() {
return environment -> {
Leg source = getSource(environment);
var boardRule = source.getBoardRule();
return new StopArrival(
source.getFrom(),
source.start(),
source.start(),
source.getBoardStopPosInPattern(),
source.getBoardingGtfsStopSequence()
source.getBoardingGtfsStopSequence(),
boardRule != null && boardRule.isNotRoutable()
);
};
}
Expand Down Expand Up @@ -247,12 +249,14 @@ public DataFetcher<Iterable<WalkStep>> steps() {
public DataFetcher<StopArrival> to() {
return environment -> {
Leg source = getSource(environment);
var alightRule = source.getAlightRule();
return new StopArrival(
source.getTo(),
source.end(),
source.end(),
source.getAlightStopPosInPattern(),
source.getAlightGtfsStopSequence()
source.getAlightGtfsStopSequence(),
alightRule != null && alightRule.isNotRoutable()
);
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public DataFetcher<VehicleRentalPlace> bikeRentalStation() {
};
}

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

@Override
public DataFetcher<VehicleParking> carPark() {
return this::getCarPark;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public DataFetcher<DebugOutput> debugOutput() {
@Override
public DataFetcher<StopArrival> from() {
return environment ->
new StopArrival(getSource(environment).getTripPlan().from, null, null, null, null);
new StopArrival(getSource(environment).getTripPlan().from, null, null, null, null, false);
}

@Override
Expand Down Expand Up @@ -115,7 +115,7 @@ public DataFetcher<Long> searchWindowUsed() {
@Override
public DataFetcher<StopArrival> to() {
return environment ->
new StopArrival(getSource(environment).getTripPlan().to, null, null, null, null);
new StopArrival(getSource(environment).getTripPlan().to, null, null, null, null, false);
}

private RoutingResponse getSource(DataFetchingEnvironment environment) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,8 @@ public interface GraphQLPlace {

public DataFetcher<VehicleRentalPlace> bikeRentalStation();

public DataFetcher<Boolean> canceled();

public DataFetcher<VehicleParking> carPark();

public DataFetcher<LegCallTime> departure();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ public List<StopArrival> getIntermediateStops() {
LegCallTime.ofStatic(ServiceDateUtils.toZonedDateTime(serviceDate, zoneId, arrivalTime)),
LegCallTime.ofStatic(ServiceDateUtils.toZonedDateTime(serviceDate, zoneId, departureTime)),
i,
tripTimes.gtfsSequenceOfStopIndex(i)
tripTimes.gtfsSequenceOfStopIndex(i),
tripTimes.isCanceled() || tripTimes.isCancelledStop(i)
);
visits.add(visit);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public final class StopArrival {
public final LegCallTime departure;
public final Integer stopPosInPattern;
public final Integer gtfsStopSequence;
public final boolean canceled;

/**
* @param arrival The time the rider will arrive at the place.
Expand All @@ -27,13 +28,15 @@ public StopArrival(
LegCallTime arrival,
LegCallTime departure,
Integer stopPosInPattern,
Integer gtfsStopSequence
Integer gtfsStopSequence,
boolean canceled
) {
this.place = place;
this.arrival = arrival;
this.departure = departure;
this.stopPosInPattern = stopPosInPattern;
this.gtfsStopSequence = gtfsStopSequence;
this.canceled = canceled;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ StopArrival map(int i, StopLocation stop, boolean realTime) {
arrival,
departure,
i,
tripTimes.gtfsSequenceOfStopIndex(i)
tripTimes.gtfsSequenceOfStopIndex(i),
tripTimes.isCanceled() || tripTimes.isCancelledStop(i)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,13 @@ type Place {
bikePark: BikePark @deprecated(reason : "bikePark is deprecated. Use vehicleParking instead.")
"The bike rental station related to the place"
bikeRentalStation: BikeRentalStation @deprecated(reason : "Use vehicleRentalStation and rentalVehicle instead")
"""
For intermediate places, if the call is cancelled by a real-time update.

For boarding and alighting places, if the rider is no longer able to board or alight at the place by a real-time update.
This can include a cancelled call or a change in pickup / drop off rules.
"""
canceled: Boolean!
"The car parking related to the place"
carPark: CarPark @deprecated(reason : "carPark is deprecated. Use vehicleParking instead.")
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Objects;
import org.junit.jupiter.api.Test;
import org.opentripplanner._support.time.ZoneIds;
import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
Expand All @@ -27,12 +28,12 @@ class ScheduledTransitLegTest {
private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of();
private static final Route ROUTE = TimetableRepositoryForTest.route(id("2")).build();
private static final TripPattern PATTERN = TimetableRepositoryForTest.tripPattern("1", ROUTE)
.withStopPattern(TEST_MODEL.stopPattern(3))
.withStopPattern(TEST_MODEL.stopPattern(4))
.build();
private static final Trip TRIP = TimetableRepositoryForTest.trip("trip1").build();
private static final ScheduledTripTimes TRIP_TIMES = ScheduledTripTimes.of()
.withArrivalTimes("10:00 11:00 12:00")
.withDepartureTimes("10:01 11:02 12:03")
.withArrivalTimes("10:00 11:00 12:00 13:00")
.withDepartureTimes("10:01 11:02 12:03 13:03")
.withTrip(TRIP)
.build();

Expand All @@ -55,8 +56,8 @@ void legTimesWithoutRealTime() {
@Test
void legTimesWithRealTime() {
var tt = ScheduledTripTimes.of()
.withArrivalTimes("10:00 11:00 12:00")
.withDepartureTimes("10:01 11:02 12:03")
.withArrivalTimes("10:00 11:00 12:00 13:00")
.withDepartureTimes("10:01 11:02 12:03 13:03")
.withTrip(TRIP)
.build();

Expand All @@ -70,12 +71,30 @@ void legTimesWithRealTime() {
assertTrue(leg.isRealTimeUpdated());
}

@Test
void legTimesWithSkippedStop() {
var rtt = RealTimeTripTimes.of(
ScheduledTripTimes.of()
.withArrivalTimes("10:00 11:00 12:00 13:00")
.withDepartureTimes("10:01 11:02 12:03 13:03")
.withGtfsSequenceOfStopIndex(new int[] { 0, 1, 2, 3 })
.withTrip(TRIP)
.build()
);
rtt.setCancelled(1);

var leg = builder().withTripTimes(rtt).build();
List<StopArrival> intermediateStops = Objects.requireNonNull(leg.getIntermediateStops());
assertTrue(intermediateStops.get(0).canceled);
assertFalse(intermediateStops.get(1).canceled);
}

private static ScheduledTransitLegBuilder builder() {
return new ScheduledTransitLegBuilder()
.withTripTimes(null)
.withTripPattern(PATTERN)
.withBoardStopIndexInPattern(0)
.withAlightStopIndexInPattern(2)
.withAlightStopIndexInPattern(3)
.withStartTime(TIME)
.withEndTime(TIME.plusMinutes(10))
.withServiceDate(TIME.toLocalDate())
Expand Down
Loading