use of org.opentripplanner.routing.edgetype.TransitBoardAlight in project OpenTripPlanner by opentripplanner.
the class TestTransfers method testStopToStopTransferWithFrequency.
public void testStopToStopTransferWithFrequency() throws Exception {
// Replace the transfer table with an empty table
TransferTable table = new TransferTable();
when(graph.getTransferTable()).thenReturn(table);
// Compute a normal path between two stops
Vertex origin = graph.getVertex(feedId + ":O");
Vertex destination = graph.getVertex(feedId + ":V");
// Set options like time and routing context
RoutingRequest options = new RoutingRequest();
options.dateTime = TestUtils.dateInSeconds("America/New_York", 2009, 7, 11, 13, 11, 0);
options.setRoutingContext(graph, origin, destination);
// Plan journey
GraphPath path;
List<Trip> trips;
path = planJourney(options);
trips = extractTrips(path);
// Validate result
assertEquals("10.5", trips.get(0).getId().getId());
assertEquals("15.1", trips.get(1).getId().getId());
// Find state with FrequencyBoard back edge and save time of that state
long time = -1;
for (State s : path.states) {
if (s.getBackEdge() instanceof TransitBoardAlight && ((TransitBoardAlight) s.getBackEdge()).boarding) {
// find the final board edge, don't break
time = s.getTimeSeconds();
}
}
assertTrue(time >= 0);
// Add transfer to table such that the next trip will be chosen
// (there are 3600 seconds between trips), transfer time was 75 seconds
Stop stopP = new Stop();
stopP.setId(new AgencyAndId(feedId, "P"));
Stop stopU = new Stop();
stopU.setId(new AgencyAndId(feedId, "U"));
table.addTransferTime(stopP, stopU, null, null, null, null, 3675);
// Plan journey
path = planJourney(options);
trips = extractTrips(path);
// Check whether a later second trip was taken
assertEquals("10.5", trips.get(0).getId().getId());
assertEquals("15.1", trips.get(1).getId().getId());
// Find state with FrequencyBoard back edge and save time of that state
long newTime = -1;
for (State s : path.states) {
if (s.getBackEdge() instanceof TransitBoardAlight && ((TransitBoardAlight) s.getBackEdge()).boarding) {
// find the final board edge, don't break
newTime = s.getTimeSeconds();
}
}
assertTrue(newTime >= 0);
assertTrue(newTime > time);
assertEquals(3600, newTime - time);
// Revert the graph, thus using the original transfer table again
reset(graph);
}
use of org.opentripplanner.routing.edgetype.TransitBoardAlight in project OpenTripPlanner by opentripplanner.
the class TestTransfers method testStopToStopTransferWithFrequencyInReverse.
public void testStopToStopTransferWithFrequencyInReverse() throws Exception {
// Replace the transfer table with an empty table
TransferTable table = new TransferTable();
when(graph.getTransferTable()).thenReturn(table);
// Compute a normal path between two stops
Vertex origin = graph.getVertex(feedId + ":U");
Vertex destination = graph.getVertex(feedId + ":J");
// Set options like time and routing context
RoutingRequest options = new RoutingRequest();
options.setArriveBy(true);
options.dateTime = TestUtils.dateInSeconds("America/New_York", 2009, 7, 11, 11, 11, 0);
options.setRoutingContext(graph, origin, destination);
// Plan journey
GraphPath path;
List<Trip> trips;
path = planJourney(options);
trips = extractTrips(path);
// Validate result
assertEquals("15.1", trips.get(0).getId().getId());
assertEquals("5.1", trips.get(1).getId().getId());
// Find state with FrequencyBoard back edge and save time of that state
long time = -1;
for (State s : path.states) {
if (s.getBackEdge() instanceof TransitBoardAlight && s.getBackState() != null) {
time = s.getBackState().getTimeSeconds();
break;
}
}
assertTrue(time >= 0);
// Add transfer to table such that the next trip will be chosen
// (there are 3600 seconds between trips), transfer time was 75 seconds
Stop stopV = new Stop();
stopV.setId(new AgencyAndId(feedId, "V"));
Stop stopI = new Stop();
stopI.setId(new AgencyAndId(feedId, "I"));
table.addTransferTime(stopV, stopI, null, null, null, null, 3675);
// Plan journey
path = planJourney(options);
trips = extractTrips(path);
// Check whether a later second trip was taken
assertEquals("15.1", trips.get(0).getId().getId());
assertEquals("5.1", trips.get(1).getId().getId());
// Find state with FrequencyBoard back edge and save time of that state
long newTime = -1;
for (State s : path.states) {
if (s.getBackEdge() instanceof TransitBoardAlight && s.getBackState() != null) {
newTime = s.getBackState().getTimeSeconds();
break;
}
}
assertTrue(newTime >= 0);
assertTrue(newTime < time);
assertEquals(3600, time - newTime);
// Revert the graph, thus using the original transfer table again
reset(graph);
}
use of org.opentripplanner.routing.edgetype.TransitBoardAlight in project OpenTripPlanner by opentripplanner.
the class TestHopFactory method testBoardAlight.
public void testBoardAlight() throws Exception {
Vertex stop_a = graph.getVertex(feedId + ":A_depart");
Vertex stop_b_depart = graph.getVertex(feedId + ":B_depart");
assertEquals(1, stop_a.getDegreeOut());
assertEquals(3, stop_b_depart.getDegreeOut());
for (Edge e : stop_a.getOutgoing()) {
assertEquals(TransitBoardAlight.class, e.getClass());
assertTrue(((TransitBoardAlight) e).boarding);
}
// TODO: could this ever be a PatternAlight? I think not.
TransitBoardAlight pb = (TransitBoardAlight) stop_a.getOutgoing().iterator().next();
Vertex journey_a_1 = pb.getToVertex();
assertEquals(1, journey_a_1.getDegreeIn());
for (Edge e : journey_a_1.getOutgoing()) {
if (e.getToVertex() instanceof TransitStop) {
assertEquals(TransitBoardAlight.class, e.getClass());
assertTrue(((TransitBoardAlight) e).boarding);
} else {
assertEquals(PatternHop.class, e.getClass());
}
}
}
use of org.opentripplanner.routing.edgetype.TransitBoardAlight in project OpenTripPlanner by opentripplanner.
the class TimetableSnapshotSourceTest method testHandleAddedTrip.
@Test
public void testHandleAddedTrip() throws ParseException {
// GIVEN
// Get service date of today because old dates will be purged after applying updates
final ServiceDate serviceDate = new ServiceDate(Calendar.getInstance());
final String addedTripId = "added_trip";
TripUpdate tripUpdate;
{
final TripDescriptor.Builder tripDescriptorBuilder = TripDescriptor.newBuilder();
tripDescriptorBuilder.setTripId(addedTripId);
tripDescriptorBuilder.setScheduleRelationship(TripDescriptor.ScheduleRelationship.ADDED);
tripDescriptorBuilder.setStartDate(serviceDate.getAsString());
final Calendar calendar = serviceDate.getAsCalendar(graph.getTimeZone());
final long midnightSecondsSinceEpoch = calendar.getTimeInMillis() / 1000;
final TripUpdate.Builder tripUpdateBuilder = TripUpdate.newBuilder();
tripUpdateBuilder.setTrip(tripDescriptorBuilder);
{
// Stop A
final StopTimeUpdate.Builder stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder();
stopTimeUpdateBuilder.setScheduleRelationship(StopTimeUpdate.ScheduleRelationship.SCHEDULED);
stopTimeUpdateBuilder.setStopId("A");
{
// Arrival
final StopTimeEvent.Builder arrivalBuilder = stopTimeUpdateBuilder.getArrivalBuilder();
arrivalBuilder.setTime(midnightSecondsSinceEpoch + (8 * 3600) + (30 * 60));
arrivalBuilder.setDelay(0);
}
{
// Departure
final StopTimeEvent.Builder departureBuilder = stopTimeUpdateBuilder.getDepartureBuilder();
departureBuilder.setTime(midnightSecondsSinceEpoch + (8 * 3600) + (30 * 60));
departureBuilder.setDelay(0);
}
}
{
// Stop C
final StopTimeUpdate.Builder stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder();
stopTimeUpdateBuilder.setScheduleRelationship(StopTimeUpdate.ScheduleRelationship.SCHEDULED);
stopTimeUpdateBuilder.setStopId("C");
{
// Arrival
final StopTimeEvent.Builder arrivalBuilder = stopTimeUpdateBuilder.getArrivalBuilder();
arrivalBuilder.setTime(midnightSecondsSinceEpoch + (8 * 3600) + (40 * 60));
arrivalBuilder.setDelay(0);
}
{
// Departure
final StopTimeEvent.Builder departureBuilder = stopTimeUpdateBuilder.getDepartureBuilder();
departureBuilder.setTime(midnightSecondsSinceEpoch + (8 * 3600) + (45 * 60));
departureBuilder.setDelay(0);
}
}
{
// Stop E
final StopTimeUpdate.Builder stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder();
stopTimeUpdateBuilder.setScheduleRelationship(StopTimeUpdate.ScheduleRelationship.SCHEDULED);
stopTimeUpdateBuilder.setStopId("E");
{
// Arrival
final StopTimeEvent.Builder arrivalBuilder = stopTimeUpdateBuilder.getArrivalBuilder();
arrivalBuilder.setTime(midnightSecondsSinceEpoch + (8 * 3600) + (55 * 60));
arrivalBuilder.setDelay(0);
}
{
// Departure
final StopTimeEvent.Builder departureBuilder = stopTimeUpdateBuilder.getDepartureBuilder();
departureBuilder.setTime(midnightSecondsSinceEpoch + (8 * 3600) + (55 * 60));
departureBuilder.setDelay(0);
}
}
tripUpdate = tripUpdateBuilder.build();
}
// WHEN
updater.applyTripUpdates(graph, fullDataset, Arrays.asList(tripUpdate), feedId);
// THEN
// Find new pattern in graph starting from stop A
Stop stopA = graph.index.stopForId.get(new AgencyAndId(feedId, "A"));
TransitStopDepart transitStopDepartA = graph.index.stopVertexForStop.get(stopA).departVertex;
// Get trip pattern of last (most recently added) outgoing edge
final List<Edge> outgoingEdges = (List<Edge>) transitStopDepartA.getOutgoing();
final TripPattern tripPattern = ((TransitBoardAlight) outgoingEdges.get(outgoingEdges.size() - 1)).getPattern();
assertNotNull("Added trip pattern should be found", tripPattern);
final TimetableSnapshot snapshot = updater.getTimetableSnapshot();
final Timetable forToday = snapshot.resolve(tripPattern, serviceDate);
final Timetable schedule = snapshot.resolve(tripPattern, null);
assertNotSame(forToday, schedule);
final int forTodayAddedTripIndex = forToday.getTripIndex(addedTripId);
assertTrue("Added trip should be found in time table for service date", forTodayAddedTripIndex > -1);
assertEquals(RealTimeState.ADDED, forToday.getTripTimes(forTodayAddedTripIndex).getRealTimeState());
final int scheduleTripIndex = schedule.getTripIndex(addedTripId);
assertEquals("Added trip should not be found in scheduled time table", -1, scheduleTripIndex);
}
use of org.opentripplanner.routing.edgetype.TransitBoardAlight in project OpenTripPlanner by opentripplanner.
the class GraphPathFinder method compactLegsByReversedSearch.
/**
* Do a full reversed search to compact the legs of the path.
*
* By doing a reversed search we are looking for later departures that will still be in time for transfer
* to the next trip, shortening the transfer wait time. Also considering other routes than the ones found
* in the original search.
*
* For arrive-by searches, we are looking to shorten transfer wait time and rather arrive earlier.
*/
private List<GraphPath> compactLegsByReversedSearch(AStar aStar, RoutingRequest originalReq, RoutingRequest options, List<GraphPath> newPaths, double timeout, RemainingWeightHeuristic remainingWeightHeuristic) {
List<GraphPath> reversedPaths = new ArrayList<>();
for (GraphPath newPath : newPaths) {
State targetAcceptedState = options.arriveBy ? newPath.states.getLast().reverse() : newPath.states.getLast();
if (targetAcceptedState.stateData.getNumBooardings() < 2) {
reversedPaths.add(newPath);
continue;
}
final long arrDepTime = targetAcceptedState.getTimeSeconds();
LOG.debug("Dep time: " + new Date(newPath.getStartTime() * 1000));
LOG.debug("Arr time: " + new Date(newPath.getEndTime() * 1000));
// find first/last transit stop
Vertex transitStop = null;
long transitStopTime = arrDepTime;
while (transitStop == null) {
if (targetAcceptedState.backEdge instanceof TransitBoardAlight) {
if (options.arriveBy) {
transitStop = targetAcceptedState.backEdge.getFromVertex();
} else {
transitStop = targetAcceptedState.backEdge.getToVertex();
}
transitStopTime = targetAcceptedState.getTimeSeconds();
}
targetAcceptedState = targetAcceptedState.getBackState();
}
// find the path from transitStop to origin/destination
Vertex fromVertex = options.arriveBy ? options.rctx.fromVertex : transitStop;
Vertex toVertex = options.arriveBy ? transitStop : options.rctx.toVertex;
RoutingRequest reversedTransitRequest = createReversedTransitRequest(originalReq, options, fromVertex, toVertex, arrDepTime, new EuclideanRemainingWeightHeuristic());
aStar.getShortestPathTree(reversedTransitRequest, timeout);
List<GraphPath> pathsToTarget = aStar.getPathsToTarget();
if (pathsToTarget.isEmpty()) {
reversedPaths.add(newPath);
continue;
}
GraphPath walkPath = pathsToTarget.get(0);
// do the reversed search to/from transitStop
Vertex fromTransVertex = options.arriveBy ? transitStop : options.rctx.fromVertex;
Vertex toTransVertex = options.arriveBy ? options.rctx.toVertex : transitStop;
RoutingRequest reversedMainRequest = createReversedMainRequest(originalReq, options, fromTransVertex, toTransVertex, transitStopTime, remainingWeightHeuristic);
aStar.getShortestPathTree(reversedMainRequest, timeout);
List<GraphPath> newRevPaths = aStar.getPathsToTarget();
if (newRevPaths.isEmpty()) {
reversedPaths.add(newPath);
} else {
List<GraphPath> joinedPaths = new ArrayList<>();
for (GraphPath newRevPath : newRevPaths) {
LOG.debug("REV Dep time: " + new Date(newRevPath.getStartTime() * 1000));
LOG.debug("REV Arr time: " + new Date(newRevPath.getEndTime() * 1000));
List<GraphPath> concatenatedPaths = Arrays.asList(newRevPath, walkPath);
if (options.arriveBy) {
Collections.reverse(concatenatedPaths);
}
GraphPath joinedPath = joinPaths(concatenatedPaths);
if ((!options.arriveBy && joinedPath.states.getFirst().getTimeInMillis() > options.dateTime * 1000) || (options.arriveBy && joinedPath.states.getLast().getTimeInMillis() < options.dateTime * 1000)) {
joinedPaths.add(joinedPath);
if (newPaths.size() > 1) {
for (AgencyAndId tripId : joinedPath.getTrips()) {
options.banTrip(tripId);
}
}
}
}
reversedPaths.addAll(joinedPaths);
}
}
return reversedPaths.isEmpty() ? newPaths : reversedPaths;
}
Aggregations