
org.opentripplanner.ext.transmodelapi.TransmodelGraphQLPlanner Maven / Gradle / Ivy
package org.opentripplanner.ext.transmodelapi;
import static org.opentripplanner.ext.transmodelapi.mapping.TransitIdMapper.mapIDsToDomain;
import graphql.execution.DataFetcherResult;
import graphql.schema.DataFetchingEnvironment;
import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.opentripplanner.ext.transmodelapi.mapping.TransitIdMapper;
import org.opentripplanner.ext.transmodelapi.model.PlanResponse;
import org.opentripplanner.ext.transmodelapi.model.TransmodelTransportSubmode;
import org.opentripplanner.ext.transmodelapi.model.TransportModeSlack;
import org.opentripplanner.ext.transmodelapi.model.plan.ItineraryFiltersInputType;
import org.opentripplanner.ext.transmodelapi.support.DataFetcherDecorator;
import org.opentripplanner.ext.transmodelapi.support.GqlUtil;
import org.opentripplanner.model.GenericLocation;
import org.opentripplanner.routing.algorithm.mapping.TripPlanMapper;
import org.opentripplanner.routing.api.request.RequestModes;
import org.opentripplanner.routing.api.request.RequestModesBuilder;
import org.opentripplanner.routing.api.request.RouteRequest;
import org.opentripplanner.routing.api.request.StreetMode;
import org.opentripplanner.routing.api.request.preference.RoutingPreferences;
import org.opentripplanner.routing.api.response.RoutingError;
import org.opentripplanner.routing.api.response.RoutingErrorCode;
import org.opentripplanner.routing.api.response.RoutingResponse;
import org.opentripplanner.routing.core.BicycleOptimizeType;
import org.opentripplanner.routing.core.RouteMatcher;
import org.opentripplanner.standalone.api.OtpServerRequestContext;
import org.opentripplanner.transit.model.basic.MainAndSubMode;
import org.opentripplanner.transit.model.basic.TransitMode;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TransmodelGraphQLPlanner {
private static final Logger LOG = LoggerFactory.getLogger(TransmodelGraphQLPlanner.class);
public DataFetcherResult plan(DataFetchingEnvironment environment) {
PlanResponse response = new PlanResponse();
TransmodelRequestContext ctx = environment.getContext();
OtpServerRequestContext serverContext = ctx.getServerContext();
RouteRequest request = null;
try {
request = createRequest(environment);
RoutingResponse res = ctx.getRoutingService().route(request);
response.plan = res.getTripPlan();
response.metadata = res.getMetadata();
response.messages = res.getRoutingErrors();
response.debugOutput = res.getDebugTimingAggregator().finishedRendering();
response.previousPageCursor = res.getPreviousPageCursor();
response.nextPageCursor = res.getNextPageCursor();
} catch (Exception e) {
LOG.error("System error: " + e.getMessage(), e);
response.plan = TripPlanMapper.mapTripPlan(request, List.of());
response.messages.add(new RoutingError(RoutingErrorCode.SYSTEM_ERROR, null));
}
Locale locale = request == null ? serverContext.defaultLocale() : request.locale();
return DataFetcherResult
.newResult()
.data(response)
.localContext(Map.of("locale", locale))
.build();
}
private GenericLocation toGenericLocation(Map m) {
Map coordinates = (Map) m.get("coordinates");
Double lat = null;
Double lon = null;
if (coordinates != null) {
lat = (Double) coordinates.get("latitude");
lon = (Double) coordinates.get("longitude");
}
String placeRef = (String) m.get("place");
FeedScopedId stopId = placeRef == null ? null : TransitIdMapper.mapIDToDomain(placeRef);
String name = (String) m.get("name");
name = name == null ? "" : name;
return new GenericLocation(name, stopId, lat, lon);
}
private RouteRequest createRequest(DataFetchingEnvironment environment) {
TransmodelRequestContext context = environment.getContext();
OtpServerRequestContext serverContext = context.getServerContext();
RouteRequest request = serverContext.defaultRouteRequest();
DataFetcherDecorator callWith = new DataFetcherDecorator(environment);
callWith.argument("locale", (String v) -> request.setLocale(Locale.forLanguageTag(v)));
callWith.argument("from", (Map v) -> request.setFrom(toGenericLocation(v)));
callWith.argument("to", (Map v) -> request.setTo(toGenericLocation(v)));
callWith.argument(
"dateTime",
millisSinceEpoch -> request.setDateTime(Instant.ofEpochMilli((long) millisSinceEpoch))
);
callWith.argument(
"searchWindow",
(Integer m) -> request.setSearchWindow(Duration.ofMinutes(m))
);
callWith.argument("pageCursor", request::setPageCursorFromEncoded);
callWith.argument("timetableView", request::setTimetableView);
callWith.argument("wheelchairAccessible", request::setWheelchair);
callWith.argument("numTripPatterns", request::setNumItineraries);
// callWith.argument("maxTransferWalkDistance", request::setMaxTransferWalkDistance);
// callWith.argument("preTransitReluctance", (Double v) -> request.setPreTransitReluctance(v));
// callWith.argument("maxPreTransitWalkDistance", (Double v) -> request.setMaxPreTransitWalkDistance(v));
// callWith.argument("transitDistanceReluctance", (Double v) -> request.transitDistanceReluctance = v);
callWith.argument("arriveBy", request::setArriveBy);
callWith.argument(
"preferred.authorities",
(Collection authorities) ->
request.journey().transit().setPreferredAgencies(mapIDsToDomain(authorities))
);
callWith.argument(
"unpreferred.authorities",
(Collection authorities) ->
request.journey().transit().setUnpreferredAgencies(mapIDsToDomain(authorities))
);
callWith.argument(
"whiteListed.authorities",
(Collection authorities) ->
request.journey().transit().setWhiteListedAgencies(mapIDsToDomain(authorities))
);
callWith.argument(
"banned.authorities",
(Collection authorities) ->
request.journey().transit().setBannedAgencies(mapIDsToDomain(authorities))
);
callWith.argument(
"preferred.lines",
(List lines) -> request.journey().transit().setPreferredRoutes(mapIDsToDomain(lines))
);
callWith.argument(
"unpreferred.lines",
(List lines) ->
request.journey().transit().setUnpreferredRoutes(mapIDsToDomain(lines))
);
callWith.argument(
"whiteListed.lines",
(List lines) ->
request
.journey()
.transit()
.setWhiteListedRoutes(RouteMatcher.idMatcher(mapIDsToDomain(lines)))
);
callWith.argument(
"banned.lines",
(List lines) ->
request.journey().transit().setBannedRoutes(RouteMatcher.idMatcher(mapIDsToDomain(lines)))
);
callWith.argument(
"banned.serviceJourneys",
(Collection serviceJourneys) ->
request.journey().transit().setBannedTrips(mapIDsToDomain(serviceJourneys))
);
// callWith.argument("banned.quays", quays -> request.setBannedStops(mappingUtil.prepareListOfFeedScopedId((List) quays)));
// callWith.argument("banned.quaysHard", quaysHard -> request.setBannedStopsHard(mappingUtil.prepareListOfFeedScopedId((List) quaysHard)));
callWith.argument(
"whiteListed.rentalNetworks",
(List networks) -> request.journey().rental().setAllowedNetworks(Set.copyOf(networks))
);
callWith.argument(
"banned.rentalNetworks",
(List networks) -> request.journey().rental().setBannedNetworks(Set.copyOf(networks))
);
// callWith.argument("heuristicStepsPerMainStep", (Integer v) -> request.heuristicStepsPerMainStep = v);
// callWith.argument("compactLegsByReversedSearch", (Boolean v) -> { /* not used any more */ });
// callWith.argument("banFirstServiceJourneysFromReuseNo", (Integer v) -> request.banFirstTripsFromReuseNo = v);
// callWith.argument("useFlex", (Boolean v) -> request.useFlexService = v);
// callWith.argument("ignoreMinimumBookingPeriod", (Boolean v) -> request.ignoreDrtAdvanceBookMin = v);
RequestModes modes = getModes(environment, callWith);
if (modes != null) {
request.journey().setModes(modes);
}
request.withPreferences(preferences -> {
mapPreferences(environment, callWith, preferences);
});
/*
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy