Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.opentripplanner.ext.legacygraphqlapi.datafetchers.LegacyGraphQLStopImpl Maven / Gradle / Ivy
package org.opentripplanner.ext.legacygraphqlapi.datafetchers;
import graphql.relay.Relay;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import java.text.ParseException;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.opentripplanner.ext.legacygraphqlapi.LegacyGraphQLRequestContext;
import org.opentripplanner.ext.legacygraphqlapi.LegacyGraphQLUtils;
import org.opentripplanner.ext.legacygraphqlapi.generated.LegacyGraphQLDataFetchers;
import org.opentripplanner.ext.legacygraphqlapi.generated.LegacyGraphQLTypes;
import org.opentripplanner.ext.legacygraphqlapi.generated.LegacyGraphQLTypes.LegacyGraphQLStopAlertType;
import org.opentripplanner.ext.legacygraphqlapi.generated.LegacyGraphQLTypes.LegacyGraphQLWheelchairBoarding;
import org.opentripplanner.model.StopTimesInPattern;
import org.opentripplanner.model.TripTimeOnDate;
import org.opentripplanner.routing.RoutingService;
import org.opentripplanner.routing.alertpatch.EntitySelector;
import org.opentripplanner.routing.alertpatch.EntitySelector.StopAndRoute;
import org.opentripplanner.routing.alertpatch.TransitAlert;
import org.opentripplanner.routing.graphfinder.NearbyStop;
import org.opentripplanner.routing.services.TransitAlertService;
import org.opentripplanner.routing.stoptimes.ArrivalDeparture;
import org.opentripplanner.transit.model.framework.AbstractTransitEntity;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.model.network.Route;
import org.opentripplanner.transit.model.network.TripPattern;
import org.opentripplanner.transit.model.site.RegularStop;
import org.opentripplanner.transit.model.site.Station;
import org.opentripplanner.transit.model.site.StopLocation;
import org.opentripplanner.transit.service.TransitService;
import org.opentripplanner.util.time.ServiceDateUtils;
public class LegacyGraphQLStopImpl implements LegacyGraphQLDataFetchers.LegacyGraphQLStop {
@Override
public DataFetcher> alerts() {
return environment -> {
TransitAlertService alertService = getTransitService(environment).getTransitAlertService();
var args = new LegacyGraphQLTypes.LegacyGraphQLStopAlertsArgs(environment.getArguments());
List types = (List) args.getLegacyGraphQLTypes();
FeedScopedId id = getValue(environment, StopLocation::getId, AbstractTransitEntity::getId);
if (types != null) {
Collection alerts = new ArrayList<>();
if (types.contains(LegacyGraphQLStopAlertType.STOP)) {
alerts.addAll(alertService.getStopAlerts(id));
}
if (
types.contains(LegacyGraphQLStopAlertType.STOP_ON_ROUTES) ||
types.contains(LegacyGraphQLStopAlertType.STOP_ON_TRIPS)
) {
alerts.addAll(
alertService
.getAllAlerts()
.stream()
.filter(alert ->
alert
.getEntities()
.stream()
.anyMatch(entity ->
(
types.contains(LegacyGraphQLStopAlertType.STOP_ON_ROUTES) &&
entity instanceof EntitySelector.StopAndRoute &&
((StopAndRoute) entity).stopAndRoute.stop.equals(id)
) ||
(
types.contains(LegacyGraphQLStopAlertType.STOP_ON_TRIPS) &&
entity instanceof EntitySelector.StopAndTrip &&
((EntitySelector.StopAndTrip) entity).stopAndTrip.stop.equals(id)
)
)
)
.collect(Collectors.toList())
);
}
if (
types.contains(LegacyGraphQLStopAlertType.PATTERNS) ||
types.contains(LegacyGraphQLStopAlertType.TRIPS)
) {
getPatterns(environment)
.forEach(pattern -> {
if (types.contains(LegacyGraphQLStopAlertType.PATTERNS)) {
alerts.addAll(
alertService.getDirectionAndRouteAlerts(
pattern.getDirection(),
pattern.getRoute().getId()
)
);
}
if (types.contains(LegacyGraphQLStopAlertType.TRIPS)) {
pattern
.scheduledTripsAsStream()
.forEach(trip -> alerts.addAll(alertService.getTripAlerts(trip.getId(), null)));
}
});
}
if (
types.contains(LegacyGraphQLStopAlertType.ROUTES) ||
types.contains(LegacyGraphQLStopAlertType.AGENCIES_OF_ROUTES)
) {
getRoutes(environment)
.forEach(route -> {
if (types.contains(LegacyGraphQLStopAlertType.ROUTES)) {
alerts.addAll(alertService.getRouteAlerts(route.getId()));
}
if (types.contains(LegacyGraphQLStopAlertType.AGENCIES_OF_ROUTES)) {
alerts.addAll(alertService.getAgencyAlerts(route.getAgency().getId()));
}
});
}
return alerts.stream().distinct().collect(Collectors.toList());
} else {
return alertService.getStopAlerts(id);
}
};
}
@Override
public DataFetcher cluster() {
return environment -> null;
}
@Override
public DataFetcher code() {
return environment -> getValue(environment, StopLocation::getCode, Station::getCode);
}
@Override
public DataFetcher desc() {
return environment ->
getValue(
environment,
stop -> LegacyGraphQLUtils.getTranslation(stop.getDescription(), environment),
station -> LegacyGraphQLUtils.getTranslation(station.getDescription(), environment)
);
}
@Override
public DataFetcher url() {
return environment ->
getValue(
environment,
stop -> LegacyGraphQLUtils.getTranslation(stop.getUrl(), environment),
station -> LegacyGraphQLUtils.getTranslation(station.getUrl(), environment)
);
}
@Override
public DataFetcher locationType() {
return environment -> getValue(environment, stop -> "STOP", station -> "STATION");
}
@Override
public DataFetcher parentStation() {
return environment -> getValue(environment, StopLocation::getParentStation, station -> null);
}
// TODO
@Override
public DataFetcher direction() {
return environment -> null;
}
@Override
public DataFetcher geometries() {
return environment -> getValue(environment, StopLocation::getGeometry, Station::getGeometry);
}
@Override
public DataFetcher gtfsId() {
return environment ->
getValue(environment, stop -> stop.getId().toString(), station -> station.getId().toString());
}
@Override
public DataFetcher id() {
return environment ->
getValue(
environment,
stop -> new Relay.ResolvedGlobalId("Stop", stop.getId().toString()),
station -> new Relay.ResolvedGlobalId("Stop", station.getId().toString())
);
}
@Override
public DataFetcher lat() {
return environment -> getValue(environment, StopLocation::getLat, Station::getLat);
}
@Override
public DataFetcher lon() {
return environment -> getValue(environment, StopLocation::getLon, Station::getLon);
}
@Override
public DataFetcher name() {
return environment ->
getValue(
environment,
stop -> LegacyGraphQLUtils.getTranslation(stop.getName(), environment),
station -> LegacyGraphQLUtils.getTranslation(station.getName(), environment)
);
}
@Override
public DataFetcher> patterns() {
return this::getPatterns;
}
@Override
public DataFetcher platformCode() {
return environment -> getValue(environment, StopLocation::getPlatformCode, station -> null);
}
@Override
public DataFetcher> routes() {
return this::getRoutes;
}
@Override
public DataFetcher> stopTimesForPattern() {
return environment ->
getValue(
environment,
stop -> {
TransitService transitService = getTransitService(environment);
LegacyGraphQLTypes.LegacyGraphQLStopStopTimesForPatternArgs args = new LegacyGraphQLTypes.LegacyGraphQLStopStopTimesForPatternArgs(
environment.getArguments()
);
TripPattern pattern = transitService.getTripPatternForId(
FeedScopedId.parseId(args.getLegacyGraphQLId())
);
if (pattern == null) {
return null;
}
if (transitService.hasRealtimeAddedTripPatterns()) {
return getTripTimeOnDatesForPatternAtStopIncludingTripsWithSkippedStops(
pattern,
stop,
transitService,
args
);
}
return transitService.stopTimesForPatternAtStop(
stop,
pattern,
LegacyGraphQLUtils.getTimeOrNow(args.getLegacyGraphQLStartTime()),
Duration.ofSeconds(args.getLegacyGraphQLTimeRange()),
args.getLegacyGraphQLNumberOfDepartures(),
args.getLegacyGraphQLOmitNonPickups()
? ArrivalDeparture.DEPARTURES
: ArrivalDeparture.BOTH,
!args.getLegacyGraphQLOmitCanceled()
);
},
station -> null
);
}
@Override
public DataFetcher> stops() {
return environment ->
getValue(
environment,
stop -> null,
station -> new ArrayList(station.getChildStops())
);
}
@Override
public DataFetcher> stoptimesForPatterns() {
return environment -> {
TransitService transitService = getTransitService(environment);
var args = new LegacyGraphQLTypes.LegacyGraphQLStopStoptimesForPatternsArgs(
environment.getArguments()
);
Function> stopTFunction = stop ->
transitService.stopTimesForStop(
stop,
LegacyGraphQLUtils.getTimeOrNow(args.getLegacyGraphQLStartTime()),
Duration.ofSeconds(args.getLegacyGraphQLTimeRange()),
args.getLegacyGraphQLNumberOfDepartures(),
args.getLegacyGraphQLOmitNonPickups()
? ArrivalDeparture.DEPARTURES
: ArrivalDeparture.BOTH,
!args.getLegacyGraphQLOmitCanceled()
);
return getValue(
environment,
stopTFunction,
station ->
station
.getChildStops()
.stream()
.map(stopTFunction)
.flatMap(Collection::stream)
.collect(Collectors.toList())
);
};
}
@Override
public DataFetcher> stoptimesForServiceDate() {
return environment -> {
TransitService transitService = getTransitService(environment);
var args = new LegacyGraphQLTypes.LegacyGraphQLStopStoptimesForServiceDateArgs(
environment.getArguments()
);
LocalDate date;
try {
date = ServiceDateUtils.parseString(args.getLegacyGraphQLDate());
} catch (ParseException e) {
return null;
}
Function> stopTFunction = stop ->
transitService.getStopTimesForStop(
stop,
date,
args.getLegacyGraphQLOmitNonPickups()
? ArrivalDeparture.DEPARTURES
: ArrivalDeparture.BOTH,
!args.getLegacyGraphQLOmitCanceled()
);
return getValue(
environment,
stopTFunction,
station ->
station
.getChildStops()
.stream()
.map(stopTFunction)
.flatMap(Collection::stream)
.collect(Collectors.toList())
);
};
}
@Override
public DataFetcher> stoptimesWithoutPatterns() {
return environment -> {
TransitService transitService = getTransitService(environment);
var args = new LegacyGraphQLTypes.LegacyGraphQLStopStoptimesForPatternsArgs(
environment.getArguments()
);
Function> stopTFunction = stop ->
transitService
.stopTimesForStop(
stop,
LegacyGraphQLUtils.getTimeOrNow(args.getLegacyGraphQLStartTime()),
Duration.ofSeconds(args.getLegacyGraphQLTimeRange()),
args.getLegacyGraphQLNumberOfDepartures(),
args.getLegacyGraphQLOmitNonPickups()
? ArrivalDeparture.DEPARTURES
: ArrivalDeparture.BOTH,
!args.getLegacyGraphQLOmitCanceled()
)
.stream();
Stream stream = getValue(
environment,
stopTFunction,
station -> station.getChildStops().stream().flatMap(stopTFunction)
);
return stream
.flatMap(stoptimesWithPattern -> stoptimesWithPattern.times.stream())
.sorted(Comparator.comparing(t -> t.getServiceDayMidnight() + t.getRealtimeDeparture()))
.limit(args.getLegacyGraphQLNumberOfDepartures())
.collect(Collectors.toList());
};
}
@Override
public DataFetcher timezone() {
return environment ->
getValue(
environment,
stop -> stop.getTimeZone().toString(),
station -> station.getTimezone().toString()
);
}
@Override
public DataFetcher> transfers() {
return environment ->
getValue(
environment,
stop -> {
Integer maxDistance = new LegacyGraphQLTypes.LegacyGraphQLStopTransfersArgs(
environment.getArguments()
)
.getLegacyGraphQLMaxDistance();
return getTransitService(environment)
.getTransfersByStop(stop)
.stream()
.filter(transfer -> maxDistance == null || transfer.getDistanceMeters() < maxDistance)
.filter(transfer -> transfer.to instanceof RegularStop)
.map(transfer ->
new NearbyStop(transfer.to, transfer.getDistanceMeters(), transfer.getEdges(), null)
)
.collect(Collectors.toList());
},
station -> null
);
}
@Override
public DataFetcher vehicleMode() {
return environment ->
getValue(
environment,
stop -> {
if (stop.getGtfsVehicleType() != null) {
return stop.getGtfsVehicleType().name();
}
return getTransitService(environment)
.getPatternsForStop(stop)
.stream()
.map(TripPattern::getMode)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.map(Enum::toString)
.orElse(null);
},
station -> {
TransitService transitService = getTransitService(environment);
return station
.getChildStops()
.stream()
.flatMap(stop ->
transitService.getPatternsForStop(stop).stream().map(TripPattern::getMode)
)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.map(Enum::toString)
.orElse(null);
}
);
}
// TODO
@Override
public DataFetcher vehicleType() {
return environment -> null;
}
@Override
public DataFetcher wheelchairBoarding() {
return environment -> {
var boarding = getValue(
environment,
StopLocation::getWheelchairAccessibility,
station -> null
);
return LegacyGraphQLUtils.toGraphQL(boarding);
};
}
@Override
public DataFetcher zoneId() {
return environment ->
getValue(environment, StopLocation::getFirstZoneAsString, station -> null);
}
private Collection getPatterns(DataFetchingEnvironment environment) {
return getValue(
environment,
stop -> getTransitService(environment).getPatternsForStop(stop, true),
station -> null
);
}
private Collection getRoutes(DataFetchingEnvironment environment) {
return getValue(
environment,
stop -> getTransitService(environment).getRoutesForStop(stop),
station -> null
);
}
private RoutingService getRoutingService(DataFetchingEnvironment environment) {
return environment.getContext().getRoutingService();
}
private TransitService getTransitService(DataFetchingEnvironment environment) {
return environment.getContext().getTransitService();
}
/**
* TODO this functionality should be supported by {@link org.opentripplanner.routing.stoptimes.StopTimesHelper#stopTimesForPatternAtStop}
*/
private List getTripTimeOnDatesForPatternAtStopIncludingTripsWithSkippedStops(
TripPattern originalPattern,
StopLocation stop,
TransitService transitService,
LegacyGraphQLTypes.LegacyGraphQLStopStopTimesForPatternArgs args
) {
Instant startTime = LegacyGraphQLUtils.getTimeOrNow(args.getLegacyGraphQLStartTime());
LocalDate date = startTime.atZone(transitService.getTimeZone()).toLocalDate();
return Stream
.concat(
getRealtimeAddedPatternsAsStream(originalPattern, transitService, date),
Stream.of(originalPattern)
)
.flatMap(tripPattern ->
transitService
.stopTimesForPatternAtStop(
stop,
tripPattern,
startTime,
Duration.ofSeconds(args.getLegacyGraphQLTimeRange()),
args.getLegacyGraphQLNumberOfDepartures(),
args.getLegacyGraphQLOmitNonPickups()
? ArrivalDeparture.DEPARTURES
: ArrivalDeparture.BOTH,
false
)
.stream()
)
.sorted(
Comparator.comparing((TripTimeOnDate tts) ->
tts.getServiceDayMidnight() + tts.getRealtimeDeparture()
)
)
.limit(args.getLegacyGraphQLNumberOfDepartures())
.toList();
}
/**
* Get a stream of {@link TripPattern} that were created realtime based of the provided pattern.
* Only patterns that don't have removed (stops can still be skipped) or added stops are included.
*/
private Stream getRealtimeAddedPatternsAsStream(
TripPattern originalPattern,
TransitService transitService,
LocalDate date
) {
return originalPattern
.scheduledTripsAsStream()
.map(trip -> transitService.getRealtimeAddedTripPattern(trip.getId(), date))
.filter(tripPattern ->
tripPattern != null && tripPattern.isModifiedFromTripPatternWithEqualStops(originalPattern)
);
}
private T getValue(
DataFetchingEnvironment environment,
Function stopTFunction,
Function stationTFunction
) {
Object source = environment.getSource();
if (source instanceof StopLocation) {
return stopTFunction.apply((StopLocation) source);
} else if (source instanceof Station) {
return stationTFunction.apply((Station) source);
}
return null;
}
}