Search in sources :

Example 1 with RoutingContext

use of org.opentripplanner.routing.core.RoutingContext in project OpenTripPlanner by opentripplanner.

the class OnBoardDepartServiceImplTest method testOnBoardAtStation.

@Test
public final void testOnBoardAtStation() {
    TransitStop station0 = mock(TransitStop.class);
    TransitStop station1 = mock(TransitStop.class);
    TransitStop station2 = mock(TransitStop.class);
    PatternDepartVertex depart = mock(PatternDepartVertex.class);
    PatternArriveVertex dwell = mock(PatternArriveVertex.class);
    PatternArriveVertex arrive = mock(PatternArriveVertex.class);
    Graph graph = mock(Graph.class);
    RoutingRequest routingRequest = mock(RoutingRequest.class);
    ServiceDay serviceDay = mock(ServiceDay.class);
    // You're probably not supposed to do this to mocks (access their fields directly)
    // But I know of no other way to do this since the mock object has only action-free stub methods.
    routingRequest.modes = new TraverseModeSet("WALK,TRANSIT");
    when(graph.getTimeZone()).thenReturn(TimeZone.getTimeZone("GMT"));
    ArrayList<Edge> hops = new ArrayList<Edge>(2);
    RoutingContext routingContext = new RoutingContext(routingRequest, graph, null, arrive);
    Agency agency = new Agency();
    AgencyAndId agencyAndId = new AgencyAndId("Agency", "ID");
    Route route = new Route();
    ArrayList<StopTime> stopTimes = new ArrayList<StopTime>(2);
    StopTime stopDepartTime = new StopTime();
    StopTime stopDwellTime = new StopTime();
    StopTime stopArriveTime = new StopTime();
    Stop stopDepart = new Stop();
    Stop stopDwell = new Stop();
    Stop stopArrive = new Stop();
    Trip trip = new Trip();
    routingContext.serviceDays = new ArrayList<ServiceDay>(Collections.singletonList(serviceDay));
    agency.setId(agencyAndId.getAgencyId());
    route.setId(agencyAndId);
    route.setAgency(agency);
    stopDepart.setId(new AgencyAndId("Station", "0"));
    stopDwell.setId(new AgencyAndId("Station", "1"));
    stopArrive.setId(new AgencyAndId("Station", "2"));
    stopDepartTime.setStop(stopDepart);
    stopDepartTime.setDepartureTime(0);
    stopDwellTime.setArrivalTime(20);
    stopDwellTime.setStop(stopDwell);
    stopDwellTime.setDepartureTime(40);
    stopArriveTime.setArrivalTime(60);
    stopArriveTime.setStop(stopArrive);
    stopTimes.add(stopDepartTime);
    stopTimes.add(stopDwellTime);
    stopTimes.add(stopArriveTime);
    trip.setId(agencyAndId);
    trip.setRoute(route);
    TripTimes tripTimes = new TripTimes(trip, stopTimes, new Deduplicator());
    StopPattern stopPattern = new StopPattern(stopTimes);
    TripPattern tripPattern = new TripPattern(route, stopPattern);
    TripPattern.generateUniqueIds(Arrays.asList(tripPattern));
    when(depart.getTripPattern()).thenReturn(tripPattern);
    when(dwell.getTripPattern()).thenReturn(tripPattern);
    PatternHop patternHop0 = new PatternHop(depart, dwell, stopDepart, stopDwell, 0);
    PatternHop patternHop1 = new PatternHop(dwell, arrive, stopDwell, stopArrive, 1);
    hops.add(patternHop0);
    hops.add(patternHop1);
    when(graph.getEdges()).thenReturn(hops);
    when(depart.getCoordinate()).thenReturn(new Coordinate(0, 0));
    when(dwell.getCoordinate()).thenReturn(new Coordinate(0, 0));
    when(arrive.getCoordinate()).thenReturn(new Coordinate(0, 0));
    routingRequest.from = new GenericLocation();
    routingRequest.startingTransitTripId = agencyAndId;
    when(graph.getVertex("Station_0")).thenReturn(station0);
    when(graph.getVertex("Station_1")).thenReturn(station1);
    when(graph.getVertex("Station_2")).thenReturn(station2);
    tripPattern.add(tripTimes);
    graph.index = new GraphIndex(graph);
    when(serviceDay.secondsSinceMidnight(anyInt())).thenReturn(0);
    assertEquals(station0, onBoardDepartServiceImpl.setupDepartOnBoard(routingContext));
    when(serviceDay.secondsSinceMidnight(anyInt())).thenReturn(20);
    assertEquals(station1, onBoardDepartServiceImpl.setupDepartOnBoard(routingContext));
    when(serviceDay.secondsSinceMidnight(anyInt())).thenReturn(30);
    assertEquals(station1, onBoardDepartServiceImpl.setupDepartOnBoard(routingContext));
    when(serviceDay.secondsSinceMidnight(anyInt())).thenReturn(40);
    assertEquals(station1, onBoardDepartServiceImpl.setupDepartOnBoard(routingContext));
    when(serviceDay.secondsSinceMidnight(anyInt())).thenReturn(60);
    assertEquals(station2, onBoardDepartServiceImpl.setupDepartOnBoard(routingContext));
}
Also used : TransitStop(org.opentripplanner.routing.vertextype.TransitStop) ServiceDay(org.opentripplanner.routing.core.ServiceDay) AgencyAndId(org.onebusaway.gtfs.model.AgencyAndId) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) ArrayList(java.util.ArrayList) Deduplicator(org.opentripplanner.routing.trippattern.Deduplicator) RoutingContext(org.opentripplanner.routing.core.RoutingContext) GraphIndex(org.opentripplanner.routing.graph.GraphIndex) PatternDepartVertex(org.opentripplanner.routing.vertextype.PatternDepartVertex) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) GenericLocation(org.opentripplanner.common.model.GenericLocation) RoutingRequest(org.opentripplanner.routing.core.RoutingRequest) Route(org.onebusaway.gtfs.model.Route) StopTime(org.onebusaway.gtfs.model.StopTime) StopPattern(org.opentripplanner.model.StopPattern) Trip(org.onebusaway.gtfs.model.Trip) Agency(org.onebusaway.gtfs.model.Agency) TraverseModeSet(org.opentripplanner.routing.core.TraverseModeSet) TripPattern(org.opentripplanner.routing.edgetype.TripPattern) Graph(org.opentripplanner.routing.graph.Graph) Coordinate(com.vividsolutions.jts.geom.Coordinate) PatternHop(org.opentripplanner.routing.edgetype.PatternHop) PatternArriveVertex(org.opentripplanner.routing.vertextype.PatternArriveVertex) Edge(org.opentripplanner.routing.graph.Edge) Test(org.junit.Test)

Example 2 with RoutingContext

use of org.opentripplanner.routing.core.RoutingContext in project OpenTripPlanner by opentripplanner.

the class OnBoardDepartServiceImplTest method testOnBoardDepartureAtArrivalTime.

@Test
public final void testOnBoardDepartureAtArrivalTime() {
    Coordinate[] coordinates = new Coordinate[2];
    coordinates[0] = new Coordinate(0.0, 0.0);
    coordinates[1] = new Coordinate(0.0, 1.0);
    TransitStop station0 = mock(TransitStop.class);
    TransitStop station1 = mock(TransitStop.class);
    PatternDepartVertex depart = mock(PatternDepartVertex.class);
    PatternArriveVertex arrive = mock(PatternArriveVertex.class);
    Graph graph = mock(Graph.class);
    RoutingRequest routingRequest = mock(RoutingRequest.class);
    ServiceDay serviceDay = mock(ServiceDay.class);
    // You're probably not supposed to do this to mocks (access their fields directly)
    // But I know of no other way to do this since the mock object has only action-free stub methods.
    routingRequest.modes = new TraverseModeSet("WALK,TRANSIT");
    when(graph.getTimeZone()).thenReturn(TimeZone.getTimeZone("GMT"));
    when(station0.getX()).thenReturn(coordinates[0].x);
    when(station0.getY()).thenReturn(coordinates[0].y);
    when(station1.getX()).thenReturn(coordinates[1].x);
    when(station1.getY()).thenReturn(coordinates[1].y);
    RoutingContext routingContext = new RoutingContext(routingRequest, graph, null, arrive);
    AgencyAndId agencyAndId = new AgencyAndId("Agency", "ID");
    Agency agency = new Agency();
    Route route = new Route();
    ArrayList<StopTime> stopTimes = new ArrayList<StopTime>(2);
    StopTime stopDepartTime = new StopTime();
    StopTime stopArriveTime = new StopTime();
    Stop stopDepart = new Stop();
    Stop stopArrive = new Stop();
    Trip trip = new Trip();
    routingContext.serviceDays = new ArrayList<ServiceDay>(Collections.singletonList(serviceDay));
    agency.setId(agencyAndId.getAgencyId());
    route.setId(agencyAndId);
    route.setAgency(agency);
    stopDepart.setId(new AgencyAndId("Station", "0"));
    stopArrive.setId(new AgencyAndId("Station", "1"));
    stopDepartTime.setStop(stopDepart);
    stopDepartTime.setDepartureTime(0);
    stopArriveTime.setArrivalTime(10);
    stopArriveTime.setStop(stopArrive);
    stopTimes.add(stopDepartTime);
    stopTimes.add(stopArriveTime);
    trip.setId(agencyAndId);
    trip.setRoute(route);
    TripTimes tripTimes = new TripTimes(trip, stopTimes, new Deduplicator());
    StopPattern stopPattern = new StopPattern(stopTimes);
    TripPattern tripPattern = new TripPattern(route, stopPattern);
    TripPattern.generateUniqueIds(Arrays.asList(tripPattern));
    when(depart.getTripPattern()).thenReturn(tripPattern);
    PatternHop patternHop = new PatternHop(depart, arrive, stopDepart, stopArrive, 0);
    when(graph.getEdges()).thenReturn(Collections.<Edge>singletonList(patternHop));
    when(depart.getCoordinate()).thenReturn(new Coordinate(0, 0));
    when(arrive.getCoordinate()).thenReturn(new Coordinate(0, 0));
    routingRequest.from = new GenericLocation();
    routingRequest.startingTransitTripId = agencyAndId;
    when(serviceDay.secondsSinceMidnight(anyInt())).thenReturn(10);
    when(graph.getVertex("Station_0")).thenReturn(station0);
    when(graph.getVertex("Station_1")).thenReturn(station1);
    tripPattern.add(tripTimes);
    graph.index = new GraphIndex(graph);
    Vertex vertex = onBoardDepartServiceImpl.setupDepartOnBoard(routingContext);
    assertEquals(coordinates[1].x, vertex.getX(), 0.0);
    assertEquals(coordinates[1].y, vertex.getY(), 0.0);
}
Also used : Vertex(org.opentripplanner.routing.graph.Vertex) PatternDepartVertex(org.opentripplanner.routing.vertextype.PatternDepartVertex) PatternArriveVertex(org.opentripplanner.routing.vertextype.PatternArriveVertex) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) ServiceDay(org.opentripplanner.routing.core.ServiceDay) AgencyAndId(org.onebusaway.gtfs.model.AgencyAndId) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) ArrayList(java.util.ArrayList) Deduplicator(org.opentripplanner.routing.trippattern.Deduplicator) RoutingContext(org.opentripplanner.routing.core.RoutingContext) GraphIndex(org.opentripplanner.routing.graph.GraphIndex) PatternDepartVertex(org.opentripplanner.routing.vertextype.PatternDepartVertex) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) GenericLocation(org.opentripplanner.common.model.GenericLocation) RoutingRequest(org.opentripplanner.routing.core.RoutingRequest) Route(org.onebusaway.gtfs.model.Route) StopTime(org.onebusaway.gtfs.model.StopTime) StopPattern(org.opentripplanner.model.StopPattern) Trip(org.onebusaway.gtfs.model.Trip) Agency(org.onebusaway.gtfs.model.Agency) TraverseModeSet(org.opentripplanner.routing.core.TraverseModeSet) TripPattern(org.opentripplanner.routing.edgetype.TripPattern) Graph(org.opentripplanner.routing.graph.Graph) Coordinate(com.vividsolutions.jts.geom.Coordinate) PatternHop(org.opentripplanner.routing.edgetype.PatternHop) PatternArriveVertex(org.opentripplanner.routing.vertextype.PatternArriveVertex) Test(org.junit.Test)

Example 3 with RoutingContext

use of org.opentripplanner.routing.core.RoutingContext in project OpenTripPlanner by opentripplanner.

the class TransitBoardAlight method traverse.

/**
 * NOTE: We do not need to check the pickup/drop off type. TransitBoardAlight edges are simply
 * not created for pick/drop type 1 (no pick/drop).
 *
 * @param arrivalTimeAtStop TODO: clarify what this is.
 */
public State traverse(State s0, long arrivalTimeAtStop) {
    RoutingContext rctx = s0.getContext();
    RoutingRequest options = s0.getOptions();
    // Forbid taking shortcuts composed of two board-alight edges in a row. Also avoids spurious leg transitions.
    if (s0.backEdge instanceof TransitBoardAlight) {
        return null;
    }
    /* If the user requested a wheelchair accessible trip, check whether and this stop is not accessible. */
    if (options.wheelchairAccessible && !getPattern().wheelchairAccessible(stopIndex)) {
        return null;
    }
    ;
    /*
         * Determine whether we are going onto or off of transit. Entering and leaving transit is
         * not the same thing as boarding and alighting. When arriveBy == true, we are entering
         * transit when traversing an alight edge backward.
         */
    boolean leavingTransit = (boarding && options.arriveBy) || (!boarding && !options.arriveBy);
    /* TODO pull on/off transit out into two functions. */
    if (leavingTransit) {
        // Perhaps this should be handled by PathParser.
        if (s0.getBackEdge() instanceof TransitBoardAlight) {
            return null;
        }
        StateEditor s1 = s0.edit(this);
        s1.setTripId(null);
        s1.setLastAlightedTimeSeconds(s0.getTimeSeconds());
        // Store the stop we are alighting at, for computing stop-to-stop transfer times,
        // preferences, and permissions.
        // The vertices in the transfer table are stop arrives/departs, not pattern
        // arrives/departs, so previousStop is direction-dependent.
        s1.setPreviousStop(getStop());
        s1.setLastPattern(this.getPattern());
        if (boarding) {
            int boardingTime = options.getBoardTime(this.getPattern().mode);
            if (boardingTime != 0) {
                // When traveling backwards the time travels also backwards
                s1.incrementTimeInSeconds(boardingTime);
                s1.incrementWeight(boardingTime * options.waitReluctance);
            }
        } else {
            int alightTime = options.getAlightTime(this.getPattern().mode);
            if (alightTime != 0) {
                s1.incrementTimeInSeconds(alightTime);
                s1.incrementWeight(alightTime * options.waitReluctance);
            // TODO: should we have different cost for alighting and boarding compared to regular waiting?
            }
        }
        /* Determine the wait. */
        if (arrivalTimeAtStop > 0) {
            // FIXME what is this arrivalTimeAtStop?
            int wait = (int) Math.abs(s0.getTimeSeconds() - arrivalTimeAtStop);
            s1.incrementTimeInSeconds(wait);
            // this should only occur at the beginning
            s1.incrementWeight(wait * options.waitAtBeginningFactor);
            s1.setInitialWaitTimeSeconds(wait);
        // LOG.debug("Initial wait time set to {} in PatternBoard", wait);
        }
        // so that comparable trip plans result (comparable to non-optimized plans)
        if (options.reverseOptimizing)
            s1.incrementWeight(options.getBoardCost(s0.getNonTransitMode()));
        if (options.reverseOptimizeOnTheFly) {
            TripPattern pattern = getPattern();
            int thisDeparture = s0.getTripTimes().getDepartureTime(stopIndex);
            int numTrips = getPattern().getNumScheduledTrips();
            int nextDeparture;
            s1.setLastNextArrivalDelta(Integer.MAX_VALUE);
            for (int tripIndex = 0; tripIndex < numTrips; tripIndex++) {
                Timetable timetable = pattern.getUpdatedTimetable(options, s0.getServiceDay());
                nextDeparture = timetable.getTripTimes(tripIndex).getDepartureTime(stopIndex);
                if (nextDeparture > thisDeparture) {
                    s1.setLastNextArrivalDelta(nextDeparture - thisDeparture);
                    break;
                }
            }
        }
        s1.setBackMode(getMode());
        return s1.makeState();
    } else {
        /* Disallow ever re-boarding the same trip pattern. */
        if (s0.getLastPattern() == this.getPattern()) {
            return null;
        }
        /* Check this pattern's mode against those allowed in the request. */
        if (!options.modes.get(modeMask)) {
            return null;
        }
        /* We assume all trips in a pattern are on the same route. Check if that route is banned. */
        if (options.bannedRoutes != null && options.bannedRoutes.matches(getPattern().route)) {
            // TODO: remove route checks in/after the trip search
            return null;
        }
        /*
             * Find the next boarding/alighting time relative to the current State. Check lists of
             * transit serviceIds running yesterday, today, and tomorrow relative to the initial
             * state. Choose the closest board/alight time among trips starting yesterday, today, or
             * tomorrow. Note that we cannot skip searching on service days that have not started
             * yet: Imagine a state at 23:59 Sunday, that should take a bus departing at 00:01
             * Monday (and coded on Monday in the GTFS); disallowing Monday's departures would
             * produce a strange plan. We also can't break off the search after we find trips today.
             * Imagine a trip on a pattern at 25:00 today and another trip on the same pattern at
             * 00:30 tommorrow. The 00:30 trip should be taken, but if we stopped the search after
             * finding today's 25:00 trip we would never find tomorrow's 00:30 trip.
             */
        TripPattern tripPattern = this.getPattern();
        int bestWait = -1;
        TripTimes bestTripTimes = null;
        ServiceDay bestServiceDay = null;
        for (ServiceDay sd : rctx.serviceDays) {
            /* Find the proper timetable (updated or original) if there is a realtime snapshot. */
            Timetable timetable = tripPattern.getUpdatedTimetable(options, sd);
            /* Skip this day/timetable if no trip in it could possibly be useful. */
            // TODO disabled until frequency representation is stable, and min/max timetable times are set from frequencies
            // However, experiments seem to show very little measurable improvement here (due to cache locality?)
            // if ( ! timetable.temporallyViable(sd, s0.getTimeSeconds(), bestWait, boarding)) continue;
            /* Find the next or prev departure depending on final boolean parameter. */
            TripTimes tripTimes = timetable.getNextTrip(s0, sd, stopIndex, boarding);
            if (tripTimes != null) {
                /* Wait is relative to departures on board and arrivals on alight. */
                int wait = boarding ? (int) (sd.time(tripTimes.getDepartureTime(stopIndex)) - s0.getTimeSeconds()) : (int) (s0.getTimeSeconds() - sd.time(tripTimes.getArrivalTime(stopIndex)));
                /* A trip was found. The wait should be non-negative. */
                if (wait < 0)
                    LOG.error("Negative wait time when boarding.");
                /* Track the soonest departure over all relevant schedules. */
                if (bestWait < 0 || wait < bestWait) {
                    bestWait = wait;
                    bestServiceDay = sd;
                    bestTripTimes = tripTimes;
                }
            }
        }
        // no appropriate trip was found
        if (bestWait < 0)
            return null;
        Trip trip = bestTripTimes.trip;
        // FIXME this should be done WHILE searching for a trip.
        if (options.tripIsBanned(trip))
            return null;
        /* Check if route is preferred by the user. */
        long preferences_penalty = options.preferencesPenaltyForRoute(getPattern().route);
        /* Compute penalty for non-preferred transfers. */
        int transferPenalty = 0;
        /* If this is not the first boarding, then we are transferring. */
        if (s0.isEverBoarded()) {
            TransferTable transferTable = options.getRoutingContext().transferTable;
            int transferTime = transferTable.getTransferTime(s0.getPreviousStop(), getStop(), s0.getPreviousTrip(), trip, boarding);
            transferPenalty = transferTable.determineTransferPenalty(transferTime, options.nonpreferredTransferPenalty);
        }
        /* Found a trip to board. Now make the child state. */
        StateEditor s1 = s0.edit(this);
        s1.setBackMode(getMode());
        s1.setServiceDay(bestServiceDay);
        // Save the trip times in the State to ensure that router has a consistent view
        // and constant-time access to them.
        s1.setTripTimes(bestTripTimes);
        s1.incrementTimeInSeconds(bestWait);
        s1.incrementNumBoardings();
        s1.setTripId(trip.getId());
        s1.setPreviousTrip(trip);
        s1.setZone(getPattern().getZone(stopIndex));
        s1.setRoute(trip.getRoute().getId());
        double wait_cost = bestWait;
        if (!s0.isEverBoarded() && !options.reverseOptimizing) {
            wait_cost *= options.waitAtBeginningFactor;
            s1.setInitialWaitTimeSeconds(bestWait);
        } else {
            wait_cost *= options.waitReluctance;
        }
        s1.incrementWeight(preferences_penalty);
        s1.incrementWeight(transferPenalty);
        // alight to prevent state domination due to free alights
        if (options.reverseOptimizing) {
            s1.incrementWeight(wait_cost);
        } else {
            s1.incrementWeight(wait_cost + options.getBoardCost(s0.getNonTransitMode()));
        }
        // impacting the possibility of this trip
        if (options.reverseOptimizeOnTheFly && !options.reverseOptimizing && s0.isEverBoarded() && s0.getLastNextArrivalDelta() <= bestWait && s0.getLastNextArrivalDelta() > -1) {
            // it is re-reversed by optimize, so this still yields a forward tree
            State optimized = s1.makeState().optimizeOrReverse(true, true);
            if (optimized == null)
                LOG.error("Null optimized state. This shouldn't happen.");
            return optimized;
        }
        /* If we didn't return an optimized path, return an unoptimized one. */
        return s1.makeState();
    }
}
Also used : Trip(org.onebusaway.gtfs.model.Trip) ServiceDay(org.opentripplanner.routing.core.ServiceDay) RoutingContext(org.opentripplanner.routing.core.RoutingContext) TransferTable(org.opentripplanner.routing.core.TransferTable) StateEditor(org.opentripplanner.routing.core.StateEditor) State(org.opentripplanner.routing.core.State) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) RoutingRequest(org.opentripplanner.routing.core.RoutingRequest)

Example 4 with RoutingContext

use of org.opentripplanner.routing.core.RoutingContext in project OpenTripPlanner by opentripplanner.

the class GraphPathToTripPlanConverterTest method testEmptyGraphPath.

/**
 * Test that empty graph paths throw a TrivialPathException
 */
@Test(expected = TrivialPathException.class)
public void testEmptyGraphPath() {
    RoutingRequest options = new RoutingRequest();
    Graph graph = new Graph();
    ExitVertex vertex = new ExitVertex(graph, "Vertex", 0, 0, 0);
    options.rctx = new RoutingContext(options, graph, vertex, vertex);
    GraphPath graphPath = new GraphPath(new State(options), false);
    GraphPathToTripPlanConverter.generateItinerary(graphPath, false, false, locale);
}
Also used : ExitVertex(org.opentripplanner.routing.vertextype.ExitVertex) RoutingContext(org.opentripplanner.routing.core.RoutingContext) Graph(org.opentripplanner.routing.graph.Graph) State(org.opentripplanner.routing.core.State) GraphPath(org.opentripplanner.routing.spt.GraphPath) RoutingRequest(org.opentripplanner.routing.core.RoutingRequest) Test(org.junit.Test)

Example 5 with RoutingContext

use of org.opentripplanner.routing.core.RoutingContext in project OpenTripPlanner by opentripplanner.

the class GraphPathToTripPlanConverterTest method buildPaths.

/**
 * Build three GraphPath objects that can be used for testing for forward, backward and onboard.
 * This method doesn't rely on any routing code.
 * Leg 0: Walking towards the train station
 * Leg 1: First train leg, interlined with leg 2
 * Leg 2: Second train leg, interlined with leg 1
 * Leg 3: Simple transfer from the train station to the ferry
 * Leg 4: Ferry leg
 * Leg 5: Walking towards the bike rental station
 * Leg 6: Cycling on a rented bike
 * Leg 7: Cycling on a rented bike, continued (to demonstrate a {@link LegSwitchingEdge})
 * Leg 8: Leaving the bike rental station on foot
 * @return An array containing the generated GraphPath objects: forward, then backward, onboard.
 */
private GraphPath[] buildPaths() {
    // This set of requested traverse modes implies that bike rental is a possibility.
    RoutingRequest options = new RoutingRequest("BICYCLE_RENT,TRANSIT");
    String feedId = "FEED";
    Graph graph = new Graph();
    // Vertices for leg 0
    ExitVertex v0 = new ExitVertex(graph, "Vertex 0", 0, 0, 0);
    IntersectionVertex v2 = new IntersectionVertex(graph, "Vertex 2", 0, 0);
    IntersectionVertex v4 = new IntersectionVertex(graph, "Vertex 4", 1, 1);
    // Stops for legs 1, 2 and 4, plus initialization and storage in a list
    Stop trainStopDepart = new Stop();
    Stop trainStopDwell = new Stop();
    Stop trainStopInterline = new Stop();
    Stop trainStopArrive = new Stop();
    Stop ferryStopDepart = new Stop();
    Stop ferryStopArrive = new Stop();
    trainStopDepart.setId(new AgencyAndId(feedId, "Depart"));
    trainStopDepart.setName("Train stop depart");
    trainStopDepart.setLon(1);
    trainStopDepart.setLat(1);
    trainStopDepart.setCode("Train depart code");
    trainStopDepart.setPlatformCode("Train depart platform");
    trainStopDepart.setZoneId("Train depart zone");
    trainStopDwell.setId(new AgencyAndId(feedId, "Dwell"));
    trainStopDwell.setName("Train stop dwell");
    trainStopDwell.setLon(45);
    trainStopDwell.setLat(23);
    trainStopDwell.setCode("Train dwell code");
    trainStopDwell.setPlatformCode("Train dwell platform");
    trainStopDwell.setZoneId("Train dwell zone");
    trainStopInterline.setId(new AgencyAndId(feedId, "Interline"));
    trainStopInterline.setName("Train stop interline");
    trainStopInterline.setLon(89);
    trainStopInterline.setLat(45);
    trainStopInterline.setCode("Train interline code");
    trainStopInterline.setPlatformCode("Train interline platform");
    trainStopInterline.setZoneId("Train interline zone");
    trainStopArrive.setId(new AgencyAndId(feedId, "Arrive"));
    trainStopArrive.setName("Train stop arrive");
    trainStopArrive.setLon(133);
    trainStopArrive.setLat(67);
    trainStopArrive.setCode("Train arrive code");
    trainStopArrive.setPlatformCode("Train arrive platform");
    trainStopArrive.setZoneId("Train arrive zone");
    ferryStopDepart.setId(new AgencyAndId(feedId, "Depart"));
    ferryStopDepart.setName("Ferry stop depart");
    ferryStopDepart.setLon(135);
    ferryStopDepart.setLat(67);
    ferryStopDepart.setCode("Ferry depart code");
    ferryStopDepart.setPlatformCode("Ferry depart platform");
    ferryStopDepart.setZoneId("Ferry depart zone");
    ferryStopArrive.setId(new AgencyAndId(feedId, "Arrive"));
    ferryStopArrive.setName("Ferry stop arrive");
    ferryStopArrive.setLon(179);
    ferryStopArrive.setLat(89);
    ferryStopArrive.setCode("Ferry arrive code");
    ferryStopArrive.setPlatformCode("Ferry arrive platform");
    ferryStopArrive.setZoneId("Ferry arrive zone");
    ArrayList<Stop> firstStops = new ArrayList<Stop>();
    ArrayList<Stop> secondStops = new ArrayList<Stop>();
    ArrayList<Stop> thirdStops = new ArrayList<Stop>();
    firstStops.add(trainStopDepart);
    firstStops.add(trainStopDwell);
    firstStops.add(trainStopInterline);
    secondStops.add(trainStopInterline);
    secondStops.add(trainStopArrive);
    thirdStops.add(ferryStopDepart);
    thirdStops.add(ferryStopArrive);
    // Agencies for legs 1, 2 and 4, plus initialization
    Agency trainAgency = new Agency();
    Agency ferryAgency = new Agency();
    trainAgency.setId("Train");
    trainAgency.setName("John Train");
    trainAgency.setUrl("http://www.train.org/");
    ferryAgency.setId("Ferry");
    ferryAgency.setName("Brian Ferry");
    ferryAgency.setUrl("http://www.ferry.org/");
    // Routes for legs 1, 2 and 4, plus initialization
    Route firstRoute = new Route();
    Route secondRoute = new Route();
    Route thirdRoute = new Route();
    firstRoute.setId(new AgencyAndId(feedId, "A"));
    firstRoute.setAgency(trainAgency);
    firstRoute.setShortName("A");
    firstRoute.setLongName("'A' Train");
    firstRoute.setType(2);
    firstRoute.setColor("White");
    firstRoute.setTextColor("Black");
    secondRoute.setId(new AgencyAndId(feedId, "B"));
    secondRoute.setAgency(trainAgency);
    secondRoute.setShortName("B");
    secondRoute.setLongName("Another Train");
    secondRoute.setType(2);
    secondRoute.setColor("Cyan");
    secondRoute.setTextColor("Yellow");
    thirdRoute.setId(new AgencyAndId(feedId, "C"));
    thirdRoute.setAgency(ferryAgency);
    thirdRoute.setShortName("C");
    thirdRoute.setLongName("Ferry Cross the Mersey");
    thirdRoute.setType(4);
    thirdRoute.setColor("Black");
    thirdRoute.setTextColor("White");
    // Trips for legs 1, 2 and 4, plus initialization
    Trip firstTrip = new Trip();
    Trip secondTrip = new Trip();
    Trip thirdTrip = new Trip();
    firstTrip.setId(new AgencyAndId(feedId, "A"));
    firstTrip.setTripShortName("A");
    firstTrip.setBlockId("Alock");
    firstTrip.setRoute(firstRoute);
    BikeAccess.setForTrip(firstTrip, BikeAccess.ALLOWED);
    firstTrip.setTripHeadsign("Street Fighting Man");
    secondTrip.setId(new AgencyAndId(feedId, "B"));
    secondTrip.setTripShortName("B");
    secondTrip.setBlockId("Block");
    secondTrip.setRoute(secondRoute);
    BikeAccess.setForTrip(secondTrip, BikeAccess.ALLOWED);
    secondTrip.setTripHeadsign("No Expectations");
    thirdTrip.setId(new AgencyAndId(feedId, "C"));
    thirdTrip.setTripShortName("C");
    thirdTrip.setBlockId("Clock");
    thirdTrip.setRoute(thirdRoute);
    BikeAccess.setForTrip(thirdTrip, BikeAccess.ALLOWED);
    thirdTrip.setTripHeadsign("Handsome Molly");
    // Scheduled stop times for legs 1, 2 and 4, plus initialization and storage in a list
    StopTime trainStopDepartTime = new StopTime();
    StopTime trainStopDwellTime = new StopTime();
    StopTime trainStopInterlineFirstTime = new StopTime();
    StopTime trainStopInterlineSecondTime = new StopTime();
    StopTime trainStopArriveTime = new StopTime();
    StopTime ferryStopDepartTime = new StopTime();
    StopTime ferryStopArriveTime = new StopTime();
    trainStopDepartTime.setTrip(firstTrip);
    trainStopDepartTime.setStop(trainStopDepart);
    trainStopDepartTime.setStopSequence(Integer.MIN_VALUE);
    trainStopDepartTime.setDepartureTime(4);
    trainStopDepartTime.setPickupType(3);
    trainStopDwellTime.setTrip(firstTrip);
    trainStopDwellTime.setStop(trainStopDwell);
    trainStopDwellTime.setStopSequence(0);
    trainStopDwellTime.setArrivalTime(8);
    trainStopDwellTime.setDepartureTime(12);
    trainStopInterlineFirstTime.setTrip(firstTrip);
    trainStopInterlineFirstTime.setStop(trainStopInterline);
    trainStopInterlineFirstTime.setStopSequence(Integer.MAX_VALUE);
    trainStopInterlineFirstTime.setArrivalTime(16);
    trainStopInterlineSecondTime.setTrip(secondTrip);
    trainStopInterlineSecondTime.setStop(trainStopInterline);
    trainStopInterlineSecondTime.setStopSequence(0);
    trainStopInterlineSecondTime.setDepartureTime(20);
    trainStopArriveTime.setTrip(secondTrip);
    trainStopArriveTime.setStop(trainStopArrive);
    trainStopArriveTime.setStopSequence(1);
    trainStopArriveTime.setArrivalTime(24);
    trainStopArriveTime.setDropOffType(2);
    ferryStopDepartTime.setTrip(thirdTrip);
    ferryStopDepartTime.setStop(ferryStopDepart);
    ferryStopDepartTime.setStopSequence(-1);
    ferryStopDepartTime.setDepartureTime(32);
    ferryStopDepartTime.setPickupType(2);
    ferryStopArriveTime.setTrip(thirdTrip);
    ferryStopArriveTime.setStop(ferryStopArrive);
    ferryStopArriveTime.setStopSequence(0);
    ferryStopArriveTime.setArrivalTime(36);
    ferryStopArriveTime.setDropOffType(3);
    ArrayList<StopTime> firstStopTimes = new ArrayList<StopTime>();
    ArrayList<StopTime> secondStopTimes = new ArrayList<StopTime>();
    ArrayList<StopTime> thirdStopTimes = new ArrayList<StopTime>();
    firstStopTimes.add(trainStopDepartTime);
    firstStopTimes.add(trainStopDwellTime);
    firstStopTimes.add(trainStopInterlineFirstTime);
    secondStopTimes.add(trainStopInterlineSecondTime);
    secondStopTimes.add(trainStopArriveTime);
    thirdStopTimes.add(ferryStopDepartTime);
    thirdStopTimes.add(ferryStopArriveTime);
    // Various patterns that are required to construct a full graph path, plus initialization
    StopPattern firstStopPattern = new StopPattern(firstStopTimes);
    StopPattern secondStopPattern = new StopPattern(secondStopTimes);
    StopPattern thirdStopPattern = new StopPattern(thirdStopTimes);
    TripPattern firstTripPattern = new TripPattern(firstRoute, firstStopPattern);
    TripPattern secondTripPattern = new TripPattern(secondRoute, secondStopPattern);
    TripPattern thirdTripPattern = new TripPattern(thirdRoute, thirdStopPattern);
    TripTimes firstTripTimes = new TripTimes(firstTrip, firstStopTimes, new Deduplicator());
    TripTimes secondTripTimes = new TripTimes(secondTrip, secondStopTimes, new Deduplicator());
    TripTimes thirdTripTimes = new TripTimes(thirdTrip, thirdStopTimes, new Deduplicator());
    firstTripPattern.add(firstTripTimes);
    secondTripPattern.add(secondTripTimes);
    thirdTripPattern.add(thirdTripTimes);
    // Vertices for legs 1, 2 and 3
    TransitStop v6 = new TransitStop(graph, trainStopDepart);
    TransitStopDepart v8 = new TransitStopDepart(graph, trainStopDepart, v6);
    // To understand the stop indexes in the vertex constructors, look at firstStopTimes.add() etc. above
    PatternDepartVertex v10 = new PatternDepartVertex(graph, firstTripPattern, 0);
    PatternArriveVertex v12 = new PatternArriveVertex(graph, firstTripPattern, 1);
    PatternDepartVertex v14 = new PatternDepartVertex(graph, firstTripPattern, 1);
    PatternArriveVertex v16 = new PatternArriveVertex(graph, firstTripPattern, 2);
    PatternDepartVertex v18 = new PatternDepartVertex(graph, secondTripPattern, 0);
    PatternArriveVertex v20 = new PatternArriveVertex(graph, secondTripPattern, 1);
    TransitStop v24 = new TransitStop(graph, trainStopArrive);
    TransitStopArrive v22 = new TransitStopArrive(graph, trainStopArrive, v24);
    // Vertices for legs 3 and 4
    TransitStop v26 = new TransitStop(graph, ferryStopDepart);
    TransitStopDepart v28 = new TransitStopDepart(graph, ferryStopDepart, v26);
    PatternDepartVertex v30 = new PatternDepartVertex(graph, thirdTripPattern, 0);
    PatternArriveVertex v32 = new PatternArriveVertex(graph, thirdTripPattern, 1);
    TransitStop v36 = new TransitStop(graph, ferryStopArrive);
    TransitStopArrive v34 = new TransitStopArrive(graph, ferryStopArrive, v36);
    // Vertices for leg 5
    IntersectionVertex v38 = new IntersectionVertex(graph, "Vertex 38", 179, 89);
    IntersectionVertex v40 = new IntersectionVertex(graph, "Vertex 40", 180, 89);
    IntersectionVertex v42 = new IntersectionVertex(graph, "Vertex 42", 180, 90);
    // Bike rental stations for legs 5, 6 and 7, plus initialization
    BikeRentalStation enterPickupStation = new BikeRentalStation();
    BikeRentalStation exitPickupStation = new BikeRentalStation();
    BikeRentalStation enterDropoffStation = new BikeRentalStation();
    BikeRentalStation exitDropoffStation = new BikeRentalStation();
    enterPickupStation.id = "Enter pickup";
    enterPickupStation.name = new NonLocalizedString("Enter pickup station");
    enterPickupStation.x = 180;
    enterPickupStation.y = 90;
    exitPickupStation.id = "Exit pickup";
    exitPickupStation.name = new NonLocalizedString("Exit pickup station");
    exitPickupStation.x = 180;
    exitPickupStation.y = 90;
    enterDropoffStation.id = "Enter dropoff";
    enterDropoffStation.name = new NonLocalizedString("Enter dropoff station");
    enterDropoffStation.x = 0;
    enterDropoffStation.y = 90;
    exitDropoffStation.id = "Exit dropoff";
    exitDropoffStation.name = new NonLocalizedString("Exit dropoff station");
    exitDropoffStation.x = 0;
    exitDropoffStation.y = 90;
    // Vertices for legs 5 and 6
    BikeRentalStationVertex v44 = new BikeRentalStationVertex(graph, enterPickupStation);
    BikeRentalStationVertex v46 = new BikeRentalStationVertex(graph, exitPickupStation);
    IntersectionVertex v48 = new IntersectionVertex(graph, "Vertex 48", 180, 90);
    IntersectionVertex v50 = new IntersectionVertex(graph, "Vertex 50", 90, 90);
    // Vertices for leg 7
    IntersectionVertex v52 = new IntersectionVertex(graph, "Vertex 52", 90, 90);
    IntersectionVertex v54 = new IntersectionVertex(graph, "Vertex 54", 0, 90);
    // Vertices for legs 7 and 8
    BikeRentalStationVertex v56 = new BikeRentalStationVertex(graph, enterDropoffStation);
    BikeRentalStationVertex v58 = new BikeRentalStationVertex(graph, exitDropoffStation);
    StreetLocation v60 = new StreetLocation("Vertex 60", new Coordinate(0, 90), "Vertex 60");
    // Vertex initialization that can't be done using the constructor
    v0.setExitName("Ausfahrt");
    v2.freeFlowing = (true);
    v4.freeFlowing = (true);
    v38.freeFlowing = (true);
    v40.freeFlowing = (true);
    v42.freeFlowing = (true);
    v48.freeFlowing = (true);
    v50.freeFlowing = (true);
    v52.freeFlowing = (true);
    v54.freeFlowing = (true);
    // Elevation profiles for the street edges that will be created later
    PackedCoordinateSequence elevation3 = new PackedCoordinateSequence.Double(new double[] { 0.0, 0.0, 3.0, 9.9 }, 2);
    PackedCoordinateSequence elevation39 = new PackedCoordinateSequence.Double(new double[] { 0.0, 9.9, 2.1, 0.1 }, 2);
    PackedCoordinateSequence elevation41 = new PackedCoordinateSequence.Double(new double[] { 0.0, 0.1, 1.9, 2.8 }, 2);
    PackedCoordinateSequence elevation49 = new PackedCoordinateSequence.Double(new double[] { 0.0, 2.8, 2.0, 2.6 }, 2);
    PackedCoordinateSequence elevation53 = new PackedCoordinateSequence.Double(new double[] { 0.0, 2.6, 1.0, 6.0 }, 2);
    // Coordinate sequences and line strings for those same edges
    PackedCoordinateSequence coordinates3 = new PackedCoordinateSequence.Double(new double[] { 0, 0, 1, 1 }, 2);
    PackedCoordinateSequence coordinates25 = new PackedCoordinateSequence.Double(new double[] { 133, 67, 135, 67 }, 2);
    PackedCoordinateSequence coordinates39 = new PackedCoordinateSequence.Double(new double[] { 179, 89, 180, 89 }, 2);
    PackedCoordinateSequence coordinates41 = new PackedCoordinateSequence.Double(new double[] { 180, 89, 180, 90 }, 2);
    PackedCoordinateSequence coordinates49 = new PackedCoordinateSequence.Double(new double[] { 180, 90, 90, 90 }, 2);
    PackedCoordinateSequence coordinates53 = new PackedCoordinateSequence.Double(new double[] { 90, 90, 0, 90 }, 2);
    GeometryFactory geometryFactory = new GeometryFactory();
    LineString l3 = new LineString(coordinates3, geometryFactory);
    LineString l25 = new LineString(coordinates25, geometryFactory);
    LineString l39 = new LineString(coordinates39, geometryFactory);
    LineString l41 = new LineString(coordinates41, geometryFactory);
    LineString l49 = new LineString(coordinates49, geometryFactory);
    LineString l53 = new LineString(coordinates53, geometryFactory);
    // Edges for leg 0
    FreeEdge e1 = new FreeEdge(v0, v2);
    StreetWithElevationEdge e3 = new StreetWithElevationEdge(v2, v4, l3, "Edge 3", 3.0, StreetTraversalPermission.ALL, false);
    // Edges for legs 1 and 2
    StreetTransitLink e5 = new StreetTransitLink(v4, v6, false);
    PreBoardEdge e7 = new PreBoardEdge(v6, v8);
    TransitBoardAlight e9 = new TransitBoardAlight(v8, v10, 0, TraverseMode.RAIL);
    PatternHop e11 = new PatternHop(v10, v12, trainStopDepart, trainStopDwell, 0);
    PatternDwell e13 = new PatternDwell(v12, v14, 1, firstTripPattern);
    PatternHop e15 = new PatternHop(v14, v16, trainStopDwell, trainStopInterline, 1);
    PatternInterlineDwell e17 = new PatternInterlineDwell(v16, v18);
    PatternHop e19 = new PatternHop(v18, v20, trainStopInterline, trainStopArrive, 0);
    TransitBoardAlight e21 = new TransitBoardAlight(v20, v22, 1, TraverseMode.RAIL);
    PreAlightEdge e23 = new PreAlightEdge(v22, v24);
    // Edges for legs 3 and 4
    SimpleTransfer e25 = new SimpleTransfer(v24, v26, 7, l25);
    PreBoardEdge e27 = new PreBoardEdge(v26, v28);
    TransitBoardAlight e29 = new TransitBoardAlight(v28, v30, 0, TraverseMode.FERRY);
    PatternHop e31 = new PatternHop(v30, v32, ferryStopDepart, ferryStopArrive, 0);
    TransitBoardAlight e33 = new TransitBoardAlight(v32, v34, 1, TraverseMode.FERRY);
    PreAlightEdge e35 = new PreAlightEdge(v34, v36);
    StreetTransitLink e37 = new StreetTransitLink(v36, v38, true);
    // Edges for legs 5 and 6, where edges 39 and 41 have the same name to trigger stayOn = true
    AreaEdge e39 = new AreaEdge(v38, v40, l39, "Edge 39 / 41", 2.1, StreetTraversalPermission.ALL, false, new AreaEdgeList());
    StreetWithElevationEdge e41 = new StreetWithElevationEdge(v40, v42, l41, "Edge 39 / 41", 1.9, StreetTraversalPermission.ALL, false);
    StreetBikeRentalLink e43 = new StreetBikeRentalLink(v42, v44);
    RentABikeOnEdge e45 = new RentABikeOnEdge(v44, v46, Collections.singleton(""));
    StreetBikeRentalLink e47 = new StreetBikeRentalLink(v46, v48);
    StreetWithElevationEdge e49 = new StreetWithElevationEdge(v48, v50, l49, "Edge 49", 2.0, StreetTraversalPermission.ALL, false);
    // Edges for legs 6, 7 and 8
    LegSwitchingEdge e51 = new LegSwitchingEdge(v50, v52);
    StreetEdge e53p = new StreetEdge(v52, v54, l53, "Edge 53", 1.0, StreetTraversalPermission.ALL, false);
    PartialStreetEdge e53 = new PartialStreetEdge(e53p, v52, v54, l53, "Edge 53", 1.0);
    StreetBikeRentalLink e55 = new StreetBikeRentalLink(v54, v56);
    RentABikeOffEdge e57 = new RentABikeOffEdge(v56, v58, Collections.singleton(""));
    StreetBikeRentalLink e59 = new StreetBikeRentalLink(v58, v60);
    // Alert for testing GTFS-RT
    AlertPatch alertPatch = new AlertPatch();
    alertPatch.setTimePeriods(Collections.singletonList(new TimePeriod(0, Long.MAX_VALUE)));
    alertPatch.setAlert(Alert.createSimpleAlerts(alertsExample));
    // Edge initialization that can't be done using the constructor
    e3.setElevationProfile(elevation3, false);
    e17.add(firstTrip, secondTrip);
    e39.setElevationProfile(elevation39, false);
    e41.setElevationProfile(elevation41, false);
    e41.setHasBogusName(true);
    e49.setElevationProfile(elevation49, false);
    e53.setElevationProfile(elevation53, false);
    graph.streetNotesService.addStaticNote(e53p, Alert.createSimpleAlerts(alertsExample), StreetNotesService.ALWAYS_MATCHER);
    // Add an extra edge to the graph in order to generate stayOn = true for one walk step.
    new StreetEdge(v40, new IntersectionVertex(graph, "Extra vertex", 180, 88), new LineString(new PackedCoordinateSequence.Double(new double[] { 180, 89, 180, 88 }, 2), geometryFactory), "Extra edge", 1.9, StreetTraversalPermission.NONE, true);
    // Various bookkeeping operations
    graph.serviceCodes.put(firstTrip.getId(), 0);
    graph.serviceCodes.put(secondTrip.getId(), 1);
    graph.serviceCodes.put(thirdTrip.getId(), 2);
    firstTripTimes.serviceCode = graph.serviceCodes.get(firstTrip.getId());
    secondTripTimes.serviceCode = graph.serviceCodes.get(secondTrip.getId());
    thirdTripTimes.serviceCode = graph.serviceCodes.get(thirdTrip.getId());
    CalendarServiceData calendarServiceData = new CalendarServiceDataStub(graph.serviceCodes.keySet());
    CalendarServiceImpl calendarServiceImpl = new CalendarServiceImpl(calendarServiceData);
    calendarServiceData.putTimeZoneForAgencyId(feedId, timeZone);
    calendarServiceData.putTimeZoneForAgencyId(feedId, timeZone);
    FareServiceStub fareServiceStub = new FareServiceStub();
    ServiceDate serviceDate = new ServiceDate(1970, 1, 1);
    // Updates for leg 4, the ferry leg
    TripDescriptor.Builder tripDescriptorBuilder = TripDescriptor.newBuilder();
    tripDescriptorBuilder.setTripId("C");
    StopTimeEvent.Builder ferryStopDepartTimeEventBuilder = StopTimeEvent.newBuilder();
    StopTimeEvent.Builder ferryStopArriveTimeEventBuilder = StopTimeEvent.newBuilder();
    ferryStopDepartTimeEventBuilder.setTime(40L);
    ferryStopArriveTimeEventBuilder.setTime(43L);
    StopTimeUpdate.Builder ferryStopDepartUpdateBuilder = StopTimeUpdate.newBuilder();
    StopTimeUpdate.Builder ferryStopArriveUpdateBuilder = StopTimeUpdate.newBuilder();
    ferryStopDepartUpdateBuilder.setStopSequence(-1);
    ferryStopDepartUpdateBuilder.setDeparture(ferryStopDepartTimeEventBuilder);
    ferryStopDepartUpdateBuilder.setArrival(ferryStopDepartTimeEventBuilder);
    ferryStopDepartUpdateBuilder.setScheduleRelationship(ScheduleRelationship.SCHEDULED);
    ferryStopArriveUpdateBuilder.setStopSequence(0);
    ferryStopArriveUpdateBuilder.setDeparture(ferryStopArriveTimeEventBuilder);
    ferryStopArriveUpdateBuilder.setArrival(ferryStopArriveTimeEventBuilder);
    ferryStopArriveUpdateBuilder.setScheduleRelationship(ScheduleRelationship.SCHEDULED);
    TripUpdate.Builder tripUpdateBuilder = TripUpdate.newBuilder();
    tripUpdateBuilder.setTrip(tripDescriptorBuilder);
    tripUpdateBuilder.addStopTimeUpdate(0, ferryStopDepartUpdateBuilder);
    tripUpdateBuilder.addStopTimeUpdate(1, ferryStopArriveUpdateBuilder);
    TripUpdate tripUpdate = tripUpdateBuilder.build();
    // Create dummy TimetableSnapshot
    TimetableSnapshot snapshot = new TimetableSnapshot();
    // Mock TimetableSnapshotSource to return dummy TimetableSnapshot
    TimetableSnapshotSource timetableSnapshotSource = mock(TimetableSnapshotSource.class);
    when(timetableSnapshotSource.getTimetableSnapshot()).thenReturn(snapshot);
    TripTimes updatedTripTimes = thirdTripPattern.scheduledTimetable.createUpdatedTripTimes(tripUpdate, timeZone, serviceDate);
    timetableSnapshotSource.getTimetableSnapshot().update(feedId, thirdTripPattern, updatedTripTimes, serviceDate);
    // Further graph initialization
    graph.putService(CalendarServiceData.class, calendarServiceData);
    graph.putService(FareService.class, fareServiceStub);
    graph.addAgency(feedId, trainAgency);
    graph.addAgency(feedId, ferryAgency);
    graph.timetableSnapshotSource = (timetableSnapshotSource);
    graph.addAlertPatch(e29, alertPatch);
    // Routing context creation and initialization
    ServiceDay serviceDay = new ServiceDay(graph, 0, calendarServiceImpl, feedId);
    // Temporary graph objects for onboard depart tests
    OnboardDepartVertex onboardDepartVertex = new OnboardDepartVertex("Onboard", 23.0, 12.0);
    OnBoardDepartPatternHop onBoardDepartPatternHop = new OnBoardDepartPatternHop(onboardDepartVertex, v12, firstTripPattern.scheduledTimetable.getTripTimes(0), serviceDay, 0, 0.5);
    // Traverse the path forward first
    RoutingRequest forwardOptions = options.clone();
    RoutingContext forwardContext = new RoutingContext(forwardOptions, graph, v0, v60);
    forwardContext.serviceDays = new ArrayList<ServiceDay>(1);
    forwardContext.serviceDays.add(serviceDay);
    forwardOptions.rctx = forwardContext;
    forwardOptions.dateTime = 0L;
    forwardOptions.bikeRentalPickupTime = 4;
    forwardOptions.bikeRentalDropoffTime = 2;
    // Forward traversal of all edges
    State s0Forward = new State(forwardOptions);
    State s2Forward = e1.traverse(s0Forward);
    State s4Forward = e3.traverse(s2Forward);
    State s6Forward = e5.traverse(s4Forward);
    State s8Forward = e7.traverse(s6Forward);
    State s10Forward = e9.traverse(s8Forward);
    State s12Forward = e11.traverse(s10Forward);
    State s14Forward = e13.traverse(s12Forward);
    State s16Forward = e15.traverse(s14Forward);
    State s18Forward = e17.traverse(s16Forward);
    State s20Forward = e19.traverse(s18Forward);
    State s22Forward = e21.traverse(s20Forward);
    State s24Forward = e23.traverse(s22Forward);
    State s26Forward = e25.traverse(s24Forward);
    State s28Forward = e27.traverse(s26Forward);
    State s30Forward = e29.traverse(s28Forward);
    State s32Forward = e31.traverse(s30Forward);
    State s34Forward = e33.traverse(s32Forward);
    State s36Forward = e35.traverse(s34Forward);
    State s38Forward = e37.traverse(s36Forward);
    State s40Forward = e39.traverse(s38Forward);
    State s42Forward = e41.traverse(s40Forward);
    State s44Forward = e43.traverse(s42Forward);
    State s46Forward = e45.traverse(s44Forward);
    State s48Forward = e47.traverse(s46Forward);
    State s50Forward = e49.traverse(s48Forward);
    State s52Forward = e51.traverse(s50Forward);
    State s54Forward = e53.traverse(s52Forward);
    State s56Forward = e55.traverse(s54Forward);
    State s58Forward = e57.traverse(s56Forward);
    State s60Forward = e59.traverse(s58Forward);
    // Also traverse the path backward
    RoutingRequest backwardOptions = options.clone();
    RoutingContext backwardContext = new RoutingContext(backwardOptions, graph, v60, v0);
    backwardContext.serviceDays = new ArrayList<ServiceDay>(1);
    backwardContext.serviceDays.add(serviceDay);
    backwardOptions.rctx = backwardContext;
    backwardOptions.dateTime = 60L;
    backwardOptions.bikeRentalPickupTime = 4;
    backwardOptions.bikeRentalDropoffTime = 2;
    backwardOptions.setArriveBy(true);
    // Backward traversal of all edges
    State s60Backward = new State(backwardOptions);
    State s58Backward = e59.traverse(s60Backward);
    State s56Backward = e57.traverse(s58Backward);
    State s54Backward = e55.traverse(s56Backward);
    State s52Backward = e53.traverse(s54Backward);
    State s50Backward = e51.traverse(s52Backward);
    State s48Backward = e49.traverse(s50Backward);
    State s46Backward = e47.traverse(s48Backward);
    State s44Backward = e45.traverse(s46Backward);
    State s42Backward = e43.traverse(s44Backward);
    State s40Backward = e41.traverse(s42Backward);
    State s38Backward = e39.traverse(s40Backward);
    State s36Backward = e37.traverse(s38Backward);
    State s34Backward = e35.traverse(s36Backward);
    State s32Backward = e33.traverse(s34Backward);
    State s30Backward = e31.traverse(s32Backward);
    State s28Backward = e29.traverse(s30Backward);
    State s26Backward = e27.traverse(s28Backward);
    State s24Backward = e25.traverse(s26Backward);
    State s22Backward = e23.traverse(s24Backward);
    State s20Backward = e21.traverse(s22Backward);
    State s18Backward = e19.traverse(s20Backward);
    State s16Backward = e17.traverse(s18Backward);
    State s14Backward = e15.traverse(s16Backward);
    State s12Backward = e13.traverse(s14Backward);
    State s10Backward = e11.traverse(s12Backward);
    State s8Backward = e9.traverse(s10Backward);
    State s6Backward = e7.traverse(s8Backward);
    State s4Backward = e5.traverse(s6Backward);
    State s2Backward = e3.traverse(s4Backward);
    State s0Backward = e1.traverse(s2Backward);
    // Perform a forward traversal starting onboard
    RoutingRequest onboardOptions = options.clone();
    RoutingContext onboardContext = new RoutingContext(onboardOptions, graph, onboardDepartVertex, v60);
    onboardContext.serviceDays = new ArrayList<ServiceDay>(1);
    onboardContext.serviceDays.add(serviceDay);
    onboardOptions.rctx = onboardContext;
    onboardOptions.dateTime = 6L;
    onboardOptions.bikeRentalPickupTime = 4;
    onboardOptions.bikeRentalDropoffTime = 2;
    // Onboard traversal of all edges
    State s10Onboard = new State(onboardOptions);
    State s12Onboard = onBoardDepartPatternHop.traverse(s10Onboard);
    State s14Onboard = e13.traverse(s12Onboard);
    State s16Onboard = e15.traverse(s14Onboard);
    State s18Onboard = e17.traverse(s16Onboard);
    State s20Onboard = e19.traverse(s18Onboard);
    State s22Onboard = e21.traverse(s20Onboard);
    State s24Onboard = e23.traverse(s22Onboard);
    State s26Onboard = e25.traverse(s24Onboard);
    State s28Onboard = e27.traverse(s26Onboard);
    State s30Onboard = e29.traverse(s28Onboard);
    State s32Onboard = e31.traverse(s30Onboard);
    State s34Onboard = e33.traverse(s32Onboard);
    State s36Onboard = e35.traverse(s34Onboard);
    State s38Onboard = e37.traverse(s36Onboard);
    State s40Onboard = e39.traverse(s38Onboard);
    State s42Onboard = e41.traverse(s40Onboard);
    State s44Onboard = e43.traverse(s42Onboard);
    State s46Onboard = e45.traverse(s44Onboard);
    State s48Onboard = e47.traverse(s46Onboard);
    State s50Onboard = e49.traverse(s48Onboard);
    State s52Onboard = e51.traverse(s50Onboard);
    State s54Onboard = e53.traverse(s52Onboard);
    State s56Onboard = e55.traverse(s54Onboard);
    State s58Onboard = e57.traverse(s56Onboard);
    State s60Onboard = e59.traverse(s58Onboard);
    return new GraphPath[] { new GraphPath(s60Forward, false), new GraphPath(s0Backward, false), new GraphPath(s60Onboard, false) };
}
Also used : PreBoardEdge(org.opentripplanner.routing.edgetype.PreBoardEdge) AgencyAndId(org.onebusaway.gtfs.model.AgencyAndId) AlertPatch(org.opentripplanner.routing.alertpatch.AlertPatch) CalendarServiceImpl(org.onebusaway.gtfs.impl.calendar.CalendarServiceImpl) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) Stop(org.onebusaway.gtfs.model.Stop) GraphPath(org.opentripplanner.routing.spt.GraphPath) NonLocalizedString(org.opentripplanner.util.NonLocalizedString) LineString(com.vividsolutions.jts.geom.LineString) Deduplicator(org.opentripplanner.routing.trippattern.Deduplicator) AreaEdge(org.opentripplanner.routing.edgetype.AreaEdge) ExitVertex(org.opentripplanner.routing.vertextype.ExitVertex) ServiceDate(org.onebusaway.gtfs.model.calendar.ServiceDate) RoutingContext(org.opentripplanner.routing.core.RoutingContext) BikeRentalStationVertex(org.opentripplanner.routing.vertextype.BikeRentalStationVertex) PatternDepartVertex(org.opentripplanner.routing.vertextype.PatternDepartVertex) TripTimes(org.opentripplanner.routing.trippattern.TripTimes) StopTimeUpdate(com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate) TransitStopArrive(org.opentripplanner.routing.vertextype.TransitStopArrive) Route(org.onebusaway.gtfs.model.Route) TimetableSnapshotSource(org.opentripplanner.updater.stoptime.TimetableSnapshotSource) StopTime(org.onebusaway.gtfs.model.StopTime) PackedCoordinateSequence(org.opentripplanner.common.geometry.PackedCoordinateSequence) StopPattern(org.opentripplanner.model.StopPattern) LegSwitchingEdge(org.opentripplanner.routing.edgetype.LegSwitchingEdge) TimePeriod(org.opentripplanner.routing.alertpatch.TimePeriod) OnboardDepartVertex(org.opentripplanner.routing.vertextype.OnboardDepartVertex) RentABikeOnEdge(org.opentripplanner.routing.edgetype.RentABikeOnEdge) StopTimeEvent(com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeEvent) Graph(org.opentripplanner.routing.graph.Graph) Coordinate(com.vividsolutions.jts.geom.Coordinate) OnBoardDepartPatternHop(org.opentripplanner.routing.edgetype.OnBoardDepartPatternHop) PatternHop(org.opentripplanner.routing.edgetype.PatternHop) State(org.opentripplanner.routing.core.State) NonLocalizedString(org.opentripplanner.util.NonLocalizedString) AreaEdgeList(org.opentripplanner.routing.edgetype.AreaEdgeList) StreetLocation(org.opentripplanner.routing.location.StreetLocation) StreetBikeRentalLink(org.opentripplanner.routing.edgetype.StreetBikeRentalLink) GeometryFactory(com.vividsolutions.jts.geom.GeometryFactory) PartialStreetEdge(org.opentripplanner.routing.edgetype.PartialStreetEdge) TransitStop(org.opentripplanner.routing.vertextype.TransitStop) ServiceDay(org.opentripplanner.routing.core.ServiceDay) TransitBoardAlight(org.opentripplanner.routing.edgetype.TransitBoardAlight) PartialStreetEdge(org.opentripplanner.routing.edgetype.PartialStreetEdge) StreetEdge(org.opentripplanner.routing.edgetype.StreetEdge) FreeEdge(org.opentripplanner.routing.edgetype.FreeEdge) PatternInterlineDwell(org.opentripplanner.routing.edgetype.PatternInterlineDwell) PreAlightEdge(org.opentripplanner.routing.edgetype.PreAlightEdge) StreetWithElevationEdge(org.opentripplanner.routing.edgetype.StreetWithElevationEdge) TripDescriptor(com.google.transit.realtime.GtfsRealtime.TripDescriptor) RoutingRequest(org.opentripplanner.routing.core.RoutingRequest) SimpleTransfer(org.opentripplanner.routing.edgetype.SimpleTransfer) TransitStopDepart(org.opentripplanner.routing.vertextype.TransitStopDepart) PatternDwell(org.opentripplanner.routing.edgetype.PatternDwell) Trip(org.onebusaway.gtfs.model.Trip) Agency(org.onebusaway.gtfs.model.Agency) TripUpdate(com.google.transit.realtime.GtfsRealtime.TripUpdate) StreetTransitLink(org.opentripplanner.routing.edgetype.StreetTransitLink) RentABikeOffEdge(org.opentripplanner.routing.edgetype.RentABikeOffEdge) TimetableSnapshot(org.opentripplanner.routing.edgetype.TimetableSnapshot) TripPattern(org.opentripplanner.routing.edgetype.TripPattern) BikeRentalStation(org.opentripplanner.routing.bike_rental.BikeRentalStation) CalendarServiceData(org.onebusaway.gtfs.model.calendar.CalendarServiceData) LineString(com.vividsolutions.jts.geom.LineString) IntersectionVertex(org.opentripplanner.routing.vertextype.IntersectionVertex) PatternArriveVertex(org.opentripplanner.routing.vertextype.PatternArriveVertex) OnBoardDepartPatternHop(org.opentripplanner.routing.edgetype.OnBoardDepartPatternHop)

Aggregations

RoutingContext (org.opentripplanner.routing.core.RoutingContext)8 RoutingRequest (org.opentripplanner.routing.core.RoutingRequest)7 Graph (org.opentripplanner.routing.graph.Graph)6 Test (org.junit.Test)5 Trip (org.onebusaway.gtfs.model.Trip)5 ServiceDay (org.opentripplanner.routing.core.ServiceDay)5 TripTimes (org.opentripplanner.routing.trippattern.TripTimes)5 Coordinate (com.vividsolutions.jts.geom.Coordinate)4 Agency (org.onebusaway.gtfs.model.Agency)4 AgencyAndId (org.onebusaway.gtfs.model.AgencyAndId)4 Route (org.onebusaway.gtfs.model.Route)4 Stop (org.onebusaway.gtfs.model.Stop)4 StopTime (org.onebusaway.gtfs.model.StopTime)4 StopPattern (org.opentripplanner.model.StopPattern)4 State (org.opentripplanner.routing.core.State)4 PatternHop (org.opentripplanner.routing.edgetype.PatternHop)4 TripPattern (org.opentripplanner.routing.edgetype.TripPattern)4 Deduplicator (org.opentripplanner.routing.trippattern.Deduplicator)4 PatternArriveVertex (org.opentripplanner.routing.vertextype.PatternArriveVertex)4 PatternDepartVertex (org.opentripplanner.routing.vertextype.PatternDepartVertex)4