Skip to content
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

add StopInPattern in GTFS GraphQL schema #6206

Open
wants to merge 5 commits into
base: dev-2.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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 @@ -61,6 +61,7 @@
import org.opentripplanner.apis.gtfs.datafetchers.RoutingErrorImpl;
import org.opentripplanner.apis.gtfs.datafetchers.StopGeometriesImpl;
import org.opentripplanner.apis.gtfs.datafetchers.StopImpl;
import org.opentripplanner.apis.gtfs.datafetchers.StopInPatternImpl;
import org.opentripplanner.apis.gtfs.datafetchers.StopOnRouteImpl;
import org.opentripplanner.apis.gtfs.datafetchers.StopOnTripImpl;
import org.opentripplanner.apis.gtfs.datafetchers.StopRelationshipImpl;
Expand Down Expand Up @@ -166,6 +167,7 @@ protected static GraphQLSchema buildSchema() {
.type(typeWiring.build(VehicleRentalNetworkImpl.class))
.type(typeWiring.build(RentalVehicleImpl.class))
.type(typeWiring.build(RentalVehicleTypeImpl.class))
.type(typeWiring.build(StopInPatternImpl.class))
.type(typeWiring.build(StopOnRouteImpl.class))
.type(typeWiring.build(StopOnTripImpl.class))
.type(typeWiring.build(UnknownImpl.class))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
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.model.StopInPatternModel;
import org.opentripplanner.apis.support.SemanticHash;
import org.opentripplanner.framework.graphql.GraphQLUtils;
import org.opentripplanner.routing.alertpatch.EntitySelector;
Expand Down Expand Up @@ -197,6 +198,19 @@ public DataFetcher<Iterable<Object>> stops() {
return this::getStops;
}

@Override
public DataFetcher<Iterable<Object>> stopsInPattern() {
return environment -> {
var pattern = getSource(environment);
var numberOfStops = pattern.numberOfStops();
var result = new StopInPatternModel[numberOfStops];
for (var i = 0; i < numberOfStops; i++) {
result[i] = StopInPatternModel.fromPatternAndIndex(pattern, i);
}
return List.of(result);
};
}

@Override
public DataFetcher<Iterable<Trip>> trips() {
return this::getTrips;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.opentripplanner.apis.gtfs.datafetchers;

import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers;
import org.opentripplanner.apis.gtfs.model.StopInPatternModel;
import org.opentripplanner.transit.model.network.TripPattern;

public class StopInPatternImpl implements GraphQLDataFetchers.GraphQLStopInPattern {

@Override
public DataFetcher<String> dropoffType() {
return environment -> StoptimeImpl.getGraphqlPickDrop(getSource(environment).dropoffType());
}

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

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

@Override
public DataFetcher<String> pickupType() {
return environment -> StoptimeImpl.getGraphqlPickDrop(getSource(environment).pickupType());
}

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

private StopInPatternModel getSource(DataFetchingEnvironment environment) {
return environment.getSource();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import javax.annotation.Nullable;
import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers;
import org.opentripplanner.apis.gtfs.generated.GraphQLTypes;
import org.opentripplanner.apis.gtfs.mapping.RealtimeStateMapper;
import org.opentripplanner.framework.graphql.GraphQLUtils;
import org.opentripplanner.model.PickDrop;
import org.opentripplanner.model.StopTime;
import org.opentripplanner.model.TripTimeOnDate;
import org.opentripplanner.transit.model.timetable.Trip;
Expand All @@ -24,14 +26,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 -> getGraphqlPickDrop(getSource(environment).getDropoffType());
}

@Override
Expand All @@ -42,14 +37,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 -> getGraphqlPickDrop(getSource(environment).getPickupType());
}

@Override
Expand Down Expand Up @@ -115,6 +103,17 @@ public DataFetcher<Trip> trip() {
return environment -> getSource(environment).getTrip();
}

@Nullable
static String getGraphqlPickDrop(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;
};
}

private TripTimeOnDate getSource(DataFetchingEnvironment environment) {
return environment.getSource();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,8 @@ public interface GraphQLPattern {

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

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

public DataFetcher<Iterable<Trip>> trips();

public DataFetcher<Iterable<Trip>> tripsForDate();
Expand Down Expand Up @@ -1049,6 +1051,18 @@ public interface GraphQLStopGeometries {
public DataFetcher<Iterable<Geometry>> googleEncoded();
}

public interface GraphQLStopInPattern {
public DataFetcher<String> dropoffType();

public DataFetcher<Integer> indexInPattern();

public DataFetcher<TripPattern> pattern();

public DataFetcher<String> pickupType();

public DataFetcher<Object> stop();
}

/** Stop that should (but not guaranteed) to exist on a route. */
public interface GraphQLStopOnRoute {
public DataFetcher<Route> route();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.opentripplanner.apis.gtfs.model;

import org.opentripplanner.model.PickDrop;
import org.opentripplanner.transit.model.network.TripPattern;
import org.opentripplanner.transit.model.site.StopLocation;

public record StopInPatternModel(
StopLocation stop,
TripPattern pattern,
int indexInPattern,
PickDrop pickupType,
PickDrop dropoffType
) {
public static StopInPatternModel fromPatternAndIndex(TripPattern pattern, int indexInPattern) {
return new StopInPatternModel(
pattern.getStop(indexInPattern),
pattern,
indexInPattern,
pattern.getBoardType(indexInPattern),
pattern.getAlightType(indexInPattern)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,8 @@ type Pattern implements Node {
semanticHash: String
"List of stops served by this pattern"
stops: [Stop!]
"List of stops with pickup / dropoff type served by this pattern"
stopsInPattern: [StopInPattern!]!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you need this for? Is it just for the index? Isn't it straightforward to compute the index yourself, first item in the list is 0 and so on?

"Trips which run on this pattern"
trips: [Trip!]
"Trips which run on this pattern on the specified date"
Expand Down Expand Up @@ -2172,6 +2174,16 @@ type StopGeometries {
googleEncoded: [Geometry]
}

type StopInPattern {
"NULL means that the stop is cancelled from the pattern."
dropoffType: PickupDropoffType
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
dropoffType: PickupDropoffType
dropOffType: PickupDropoffType

indexInPattern: Int!
pattern: Pattern!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need the pattern? Seems like you already have it.

"NULL means that the stop is cancelled from the pattern."
pickupType: PickupDropoffType
stop: Stop!
}

"Stop that should (but not guaranteed) to exist on a route."
type StopOnRoute {
"Route which contains the stop."
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.opentripplanner.apis.gtfs.model;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id;

import org.junit.jupiter.api.Test;
import org.opentripplanner.model.PickDrop;
import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
import org.opentripplanner.transit.model.network.Route;
import org.opentripplanner.transit.model.network.StopPattern;
import org.opentripplanner.transit.model.network.TripPattern;
import org.opentripplanner.transit.model.site.RegularStop;

public class StopInPatternModelTest {

private static final String ID = "1";
private static final String NAME = "short name";
private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of();

private static final Route ROUTE = TimetableRepositoryForTest.route("routeId").build();
public static final RegularStop STOP_A = TEST_MODEL.stop("A").build();
public static final RegularStop STOP_B = TEST_MODEL.stop("B").build();
public static final RegularStop STOP_C = TEST_MODEL.stop("C").build();
private static final StopPattern STOP_PATTERN = getStopPattern();

private static StopPattern getStopPattern() {
var builder = StopPattern.create(3);

builder.stops.with(0, STOP_A);
builder.stops.with(1, STOP_B);
builder.stops.with(2, STOP_C);
builder.pickups.with(0, PickDrop.SCHEDULED);
builder.pickups.with(1, PickDrop.CALL_AGENCY);
builder.pickups.with(2, PickDrop.NONE);
builder.dropoffs.with(0, PickDrop.NONE);
builder.dropoffs.with(1, PickDrop.COORDINATE_WITH_DRIVER);
builder.dropoffs.with(2, PickDrop.SCHEDULED);
return builder.build();
}

public static final TripPattern PATTERN = TripPattern
.of(id(ID))
.withName(NAME)
.withRoute(ROUTE)
.withStopPattern(STOP_PATTERN)
.build();

@Test
public void fromPatternAndIndex() {
assertEquals(
new StopInPatternModel(STOP_A, PATTERN, 0, PickDrop.SCHEDULED, PickDrop.NONE),
StopInPatternModel.fromPatternAndIndex(PATTERN, 0)
);
assertEquals(
new StopInPatternModel(
STOP_B,
PATTERN,
1,
PickDrop.CALL_AGENCY,
PickDrop.COORDINATE_WITH_DRIVER
),
StopInPatternModel.fromPatternAndIndex(PATTERN, 1)
);
assertEquals(
new StopInPatternModel(STOP_C, PATTERN, 2, PickDrop.NONE, PickDrop.SCHEDULED),
StopInPatternModel.fromPatternAndIndex(PATTERN, 2)
);
}
}
Loading