* @param n allows building several request objects from the same query parameters,
* re-specifying only those parameters that change from one request to the next.
* @throws ParameterException when there is a problem interpreting a query parameter
*/
protected RoutingRequest buildRequest(int n) throws ParameterException {
RoutingRequest request = otpServer.routingRequest.clone();
request.setFromString(get(fromPlace, n, request.getFromPlace().getRepresentation()));
request.setToString(get(toPlace, n, request.getToPlace().getRepresentation()));
request.routerId = routerId;
{
//FIXME: get defaults for these from request
String d = get(date, n, null);
String t = get(time, n, null);
TimeZone tz;
if (otpServer.graphService != null) { // in tests graphService can be null
tz = otpServer.graphService.getGraph(request.routerId).getTimeZone();
} else {
LOG.warn("No graph service available, using default time zone.");
tz = TimeZone.getDefault();
LOG.info("Time zone set to {}", tz);
}
if (d == null && t != null) { // Time was provided but not date
LOG.debug("parsing ISO datetime {}", t);
try {
// If the time query param doesn't specify a timezone, use the graph's default. See issue #1373.
DatatypeFactory df = javax.xml.datatype.DatatypeFactory.newInstance();
XMLGregorianCalendar xmlGregCal = df.newXMLGregorianCalendar(t);
GregorianCalendar gregCal = xmlGregCal.toGregorianCalendar();
if (xmlGregCal.getTimezone() == DatatypeConstants.FIELD_UNDEFINED) {
gregCal.setTimeZone(tz);
}
Date d2 = gregCal.getTime();
request.setDateTime(d2);
} catch (DatatypeConfigurationException e) {
request.setDateTime(d, t, tz);
}
} else {
request.setDateTime(d, t, tz);
}
}
request.setWheelchairAccessible(get(wheelchair, n, request.wheelchairAccessible));
request.setNumItineraries(get(numItineraries, n, request.getNumItineraries()));
request.setMaxWalkDistance(get(maxWalkDistance, n, request.getMaxWalkDistance()));
request.setMaxPreTransitTime(get(maxPreTransitTime, n, request.maxPreTransitTime));
request.setWalkReluctance(get(walkReluctance, n, request.walkReluctance));
request.setWaitReluctance(get(waitReluctance, n, request.waitReluctance));
request.setWaitAtBeginningFactor(get(waitAtBeginningFactor, n, request.waitAtBeginningFactor));
request.walkSpeed = get(walkSpeed, n, request.walkSpeed);
double bikeSpeedParam = get(bikeSpeed, n, request.bikeSpeed);
request.bikeSpeed = bikeSpeedParam;
int bikeSwitchTimeParam = get(bikeSwitchTime, n, request.bikeSwitchTime);
request.bikeSwitchTime = bikeSwitchTimeParam;
int bikeSwitchCostParam = get(bikeSwitchCost, n, request.bikeSwitchCost);
request.bikeSwitchCost = bikeSwitchCostParam;
OptimizeType opt = get(optimize, n, request.optimize);
{
Double tsafe = get(triangleSafetyFactor, n, null);
Double tslope = get(triangleSlopeFactor, n, null);
Double ttime = get(triangleTimeFactor, n, null);
if (tsafe != null || tslope != null || ttime != null ) {
if (tsafe == null || tslope == null || ttime == null) {
throw new ParameterException(Message.UNDERSPECIFIED_TRIANGLE);
}
if (opt == null) {
opt = OptimizeType.TRIANGLE;
} else if (opt != OptimizeType.TRIANGLE) {
throw new ParameterException(Message.TRIANGLE_OPTIMIZE_TYPE_NOT_SET);
}
if (Math.abs(tsafe + tslope + ttime - 1) > Math.ulp(1) * 3) {
throw new ParameterException(Message.TRIANGLE_NOT_AFFINE);
}
request.setTriangleSafetyFactor(tsafe);
request.setTriangleSlopeFactor(tslope);
request.setTriangleTimeFactor(ttime);
} else if (opt == OptimizeType.TRIANGLE) {
throw new ParameterException(Message.TRIANGLE_VALUES_NOT_SET);
}
}
request.setArriveBy(get(arriveBy, n, false));
request.showIntermediateStops = get(showIntermediateStops, n, request.showIntermediateStops);
/* intermediate places and their ordering are shared because they are themselves a list */
if (intermediatePlaces != null && intermediatePlaces.size() > 0
&& ! intermediatePlaces.get(0).equals("")) {
request.setIntermediatePlacesFromStrings(intermediatePlaces);
}
if (intermediatePlacesOrdered == null)
intermediatePlacesOrdered = request.intermediatePlacesOrdered;
request.intermediatePlacesOrdered = intermediatePlacesOrdered;
request.setPreferredRoutes(get(preferredRoutes, n, request.getPreferredRouteStr()));
request.setOtherThanPreferredRoutesPenalty(get(otherThanPreferredRoutesPenalty, n, request.otherThanPreferredRoutesPenalty));
request.setPreferredAgencies(get(preferredAgencies, n, request.getPreferredAgenciesStr()));
request.setUnpreferredRoutes(get(unpreferredRoutes, n, request.getUnpreferredRouteStr()));
request.setUnpreferredAgencies(get(unpreferredAgencies, n, request.getUnpreferredAgenciesStr()));
request.setWalkBoardCost(get(walkBoardCost, n, request.walkBoardCost));
request.setBikeBoardCost(get(bikeBoardCost, n, request.bikeBoardCost));
request.setBannedRoutes(get(bannedRoutes, n, request.getBannedRouteStr()));
request.setBannedAgencies(get(bannedAgencies, n, request.getBannedAgenciesStr()));
HashMap<AgencyAndId, BannedStopSet> bannedTripMap = makeBannedTripMap(get(bannedTrips, n, null));
if (bannedTripMap != null) {
request.bannedTrips = bannedTripMap;
}
request.setBannedStops(get(bannedStops, n, request.getBannedStopsStr()));
request.setBannedStopsHard(get(bannedStopsHard, n, request.getBannedStopsHardStr()));
// "Least transfers" optimization is accomplished via an increased transfer penalty.
// See comment on RoutingRequest.transferPentalty.
if (opt == OptimizeType.TRANSFERS) {
opt = OptimizeType.QUICK;
request.transferPenalty = get(transferPenalty, n, 0) + 1800;
} else {
request.transferPenalty = (get(transferPenalty, n, request.transferPenalty));
}
request.batch = (get(batch, n, new Boolean(request.batch)));
request.setOptimize(opt);
/* Temporary code to get bike/car parking and renting working. */
modes.get(0).applyToRequest(request);
if (request.allowBikeRental && bikeSpeedParam == -1) {
//slower bike speed for bike sharing, based on empirical evidence from DC.
request.bikeSpeed = 4.3;
}
request.boardSlack = (get(boardSlack, n, request.boardSlack));
request.alightSlack = (get(alightSlack, n, request.alightSlack));
request.transferSlack = (get(minTransferTime, n, request.transferSlack));
request.nonpreferredTransferPenalty = get(nonpreferredTransferPenalty, n, request.nonpreferredTransferPenalty);
if (request.boardSlack + request.alightSlack > request.transferSlack) {
throw new RuntimeException("Invalid parameters: transfer slack must "
+ "be greater than or equal to board slack plus alight slack");
}
request.setMaxTransfers(get(maxTransfers, n, request.maxTransfers));
final long NOW_THRESHOLD_MILLIS = 15 * 60 * 60 * 1000;
boolean tripPlannedForNow = Math.abs(request.getDateTime().getTime() - new Date().getTime())
< NOW_THRESHOLD_MILLIS;
request.useBikeRentalAvailabilityInformation = (tripPlannedForNow);
if (request.intermediatePlaces != null
&& (request.modes.isTransit() ||
(request.modes.getWalk() &&