/** * Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onebusaway.transit_data_federation.impl.otp.graph.tp; import java.util.List; import org.onebusaway.collections.tuple.Pair; import org.onebusaway.transit_data_federation.impl.otp.GraphContext; import org.onebusaway.transit_data_federation.impl.otp.ItineraryWeightingLibrary; import org.onebusaway.transit_data_federation.impl.otp.OBAStateEditor; import org.onebusaway.transit_data_federation.impl.otp.OBATraverseOptions; import org.onebusaway.transit_data_federation.impl.otp.graph.AbstractEdge; import org.onebusaway.transit_data_federation.model.TargetTime; import org.onebusaway.transit_data_federation.services.ArrivalAndDeparturePairQuery; import org.onebusaway.transit_data_federation.services.ArrivalAndDepartureService; import org.onebusaway.transit_data_federation.services.realtime.ArrivalAndDepartureInstance; import org.onebusaway.transit_data_federation.services.transit_graph.StopEntry; import org.opentripplanner.routing.core.EdgeNarrative; import org.opentripplanner.routing.core.State; import org.opentripplanner.routing.core.TraverseOptions; import org.opentripplanner.routing.core.Vertex; public class TPDepartureEdge extends AbstractEdge { private TPState _pathState; public TPDepartureEdge(GraphContext context, TPState pathState) { super(context); _pathState = pathState; } @Override public State traverse(State s0) { TraverseOptions options = s0.getOptions(); if (options.isArriveBy()) return traverseReverse(s0); else return traverseForward(s0); } private State traverseForward(State s0) { OBATraverseOptions obaOpts = (OBATraverseOptions) s0.getOptions(); ArrivalAndDepartureService adService = _context.getArrivalAndDepartureService(); Vertex fromV = new TPDepartureVertex(_context, _pathState); Pair<StopEntry> stopPair = _pathState.getStops(); TargetTime targetTime = new TargetTime(s0.getTime(), obaOpts.currentTime); ArrivalAndDeparturePairQuery query = new ArrivalAndDeparturePairQuery(); query.setResultCount(obaOpts.numItineraries); query.setApplyRealTime(obaOpts.useRealtime); query.setIncludePrivateService(false); if (s0.getNumBoardings() == 0) query.setLookaheadTime(obaOpts.lookaheadTime); List<Pair<ArrivalAndDepartureInstance>> instances = adService.getNextDeparturesForStopPair( stopPair.getFirst(), stopPair.getSecond(), targetTime, query); State results = null; for (Pair<ArrivalAndDepartureInstance> pair : instances) { ArrivalAndDepartureInstance departure = pair.getFirst(); if (departure.getBestDepartureTime() < s0.getTime() - query.getLookaheadTime() * 1000) continue; Vertex toV = new TPBlockDepartureVertex(_context, _pathState, departure, pair.getSecond()); int dwellTime = computeWaitTime(s0, pair); double w = ItineraryWeightingLibrary.computeWeightForWait(s0, dwellTime); EdgeNarrative narrative = narrative(s0, fromV, toV); OBAStateEditor edit = (OBAStateEditor) s0.edit(this, narrative); edit.setTime(departure.getBestDepartureTime()); edit.incrementWeight(w); /** * If the departure time is less than the starting state time, it must * mean the departure was included as determined by the lookahead * parameter. Thus, we indicate that we have a lookahead itinerary. */ if (departure.getBestDepartureTime() < s0.getTime()) edit.setLookaheadItinerary(); if (departure.getBlockSequence() != null) edit.appendTripSequence(departure.getBlockSequence()); else edit.appendTripSequence(departure.getBlockTrip()); State s1 = edit.makeState(); results = s1.addToExistingResultChain(results); } return results; } private State traverseReverse(State s0) { TPDepartureVertex fromVertex = new TPDepartureVertex(_context, _pathState); Vertex toVertex = null; EdgeNarrative narrative = narrative(s0, fromVertex, toVertex); return s0.edit(this, narrative).makeState(); } /**** * ****/ private int computeWaitTime(State s0, Pair<ArrivalAndDepartureInstance> pair) { int waitTime = (int) ((pair.getFirst().getBestDepartureTime() - s0.getTime()) / 1000); // If we have a lookahead departure, the wait time will actually be zero return Math.max(waitTime, 0); } }