Search in sources :

Example 11 with TimepointPredictionRecord

use of org.onebusaway.realtime.api.TimepointPredictionRecord in project onebusaway-application-modules by camsys.

the class SiriSupport method fillMonitoredVehicleJourney.

/**
 * NOTE: The tripDetails bean here may not be for the trip the vehicle is currently on
 * in the case of A-D for stop!
 */
@SuppressWarnings("unused")
public static void fillMonitoredVehicleJourney(MonitoredVehicleJourneyStructure monitoredVehicleJourney, TripBean framedJourneyTripBean, TripStatusBean currentVehicleTripStatus, StopBean monitoredCallStopBean, OnwardCallsMode onwardCallsMode, PresentationService presentationService, TransitDataService transitDataService, int maximumOnwardCalls, List<TimepointPredictionRecord> stopLevelPredictions, boolean hasRealtimeData, long responseTimestamp, boolean showRawLocation) {
    BlockInstanceBean blockInstance = transitDataService.getBlockInstance(currentVehicleTripStatus.getActiveTrip().getBlockId(), currentVehicleTripStatus.getServiceDate());
    List<BlockTripBean> blockTrips = blockInstance.getBlockConfiguration().getTrips();
    if (monitoredCallStopBean == null) {
        monitoredCallStopBean = currentVehicleTripStatus.getNextStop();
    }
    // ///////////
    LineRefStructure lineRef = new LineRefStructure();
    lineRef.setValue(framedJourneyTripBean.getRoute().getId());
    monitoredVehicleJourney.setLineRef(lineRef);
    OperatorRefStructure operatorRef = new OperatorRefStructure();
    operatorRef.setValue(framedJourneyTripBean.getRoute().getId().split("_")[0]);
    monitoredVehicleJourney.setOperatorRef(operatorRef);
    DirectionRefStructure directionRef = new DirectionRefStructure();
    directionRef.setValue(framedJourneyTripBean.getDirectionId());
    monitoredVehicleJourney.setDirectionRef(directionRef);
    NaturalLanguageStringStructure routeShortName = new NaturalLanguageStringStructure();
    String shortName = framedJourneyTripBean.getRoute().getShortName();
    if (shortName == null) {
        shortName = framedJourneyTripBean.getRoute().getId().split("_")[1];
    }
    if (!isBlank(currentVehicleTripStatus.getActiveTrip().getRouteShortName())) {
        // look for an override like an express desginator
        routeShortName.setValue(currentVehicleTripStatus.getActiveTrip().getRouteShortName());
    } else {
        routeShortName.setValue(shortName);
    }
    monitoredVehicleJourney.setPublishedLineName(routeShortName);
    JourneyPatternRefStructure journeyPattern = new JourneyPatternRefStructure();
    journeyPattern.setValue(framedJourneyTripBean.getShapeId());
    monitoredVehicleJourney.setJourneyPatternRef(journeyPattern);
    NaturalLanguageStringStructure headsign = new NaturalLanguageStringStructure();
    headsign.setValue(framedJourneyTripBean.getTripHeadsign());
    monitoredVehicleJourney.setDestinationName(headsign);
    VehicleRefStructure vehicleRef = new VehicleRefStructure();
    if (currentVehicleTripStatus.getVehicleId() == null) {
        String tripId = framedJourneyTripBean.getId();
        String blockId = framedJourneyTripBean.getBlockId();
        String directionId = framedJourneyTripBean.getDirectionId();
        String vehicleIdHash = Integer.toString((tripId + blockId + directionId).hashCode());
        String agencyName = tripId.split("_")[0];
        String vehicleId = agencyName + "_" + vehicleIdHash;
        vehicleRef.setValue(vehicleId);
    } else {
        vehicleRef.setValue(currentVehicleTripStatus.getVehicleId());
    }
    monitoredVehicleJourney.setVehicleRef(vehicleRef);
    monitoredVehicleJourney.getVehicleMode().add(toVehicleMode(currentVehicleTripStatus.getVehicleType()));
    monitoredVehicleJourney.setMonitored(currentVehicleTripStatus.isPredicted());
    monitoredVehicleJourney.setBearing((float) currentVehicleTripStatus.getOrientation());
    monitoredVehicleJourney.setProgressRate(getProgressRateForPhaseAndStatus(currentVehicleTripStatus.getStatus(), currentVehicleTripStatus.getPhase()));
    // origin-destination
    for (int i = 0; i < blockTrips.size(); i++) {
        BlockTripBean blockTrip = blockTrips.get(i);
        if (blockTrip.getTrip().getId().equals(framedJourneyTripBean.getId())) {
            List<BlockStopTimeBean> stops = blockTrip.getBlockStopTimes();
            JourneyPlaceRefStructure origin = new JourneyPlaceRefStructure();
            origin.setValue(stops.get(0).getStopTime().getStop().getId());
            monitoredVehicleJourney.setOriginRef(origin);
            StopBean lastStop = stops.get(stops.size() - 1).getStopTime().getStop();
            DestinationRefStructure dest = new DestinationRefStructure();
            dest.setValue(lastStop.getId());
            monitoredVehicleJourney.setDestinationRef(dest);
            break;
        }
    }
    // framed journey
    FramedVehicleJourneyRefStructure framedJourney = new FramedVehicleJourneyRefStructure();
    DataFrameRefStructure dataFrame = new DataFrameRefStructure();
    dataFrame.setValue(String.format("%1$tY-%1$tm-%1$td", currentVehicleTripStatus.getServiceDate()));
    framedJourney.setDataFrameRef(dataFrame);
    framedJourney.setDatedVehicleJourneyRef(framedJourneyTripBean.getId());
    monitoredVehicleJourney.setFramedVehicleJourneyRef(framedJourney);
    // location
    // if vehicle is detected to be on detour, use actual lat/lon, not snapped location.
    LocationStructure location = new LocationStructure();
    DecimalFormat df = new DecimalFormat();
    df.setMaximumFractionDigits(6);
    // if we want to show the raw location AND we have realtime or if its on detour, show actual location
    if ((showRawLocation && currentVehicleTripStatus.getLastKnownLocation() != null) || (presentationService.isOnDetour(currentVehicleTripStatus))) {
        location.setLatitude(new BigDecimal(df.format(currentVehicleTripStatus.getLastKnownLocation().getLat())));
        location.setLongitude(new BigDecimal(df.format(currentVehicleTripStatus.getLastKnownLocation().getLon())));
    } else {
        // show snapped location
        if (currentVehicleTripStatus.getLocation() != null) {
            location.setLatitude(new BigDecimal(df.format(currentVehicleTripStatus.getLocation().getLat())));
            location.setLongitude(new BigDecimal(df.format(currentVehicleTripStatus.getLocation().getLon())));
        }
    }
    monitoredVehicleJourney.setVehicleLocation(location);
    // progress status
    List<String> progressStatuses = new ArrayList<String>();
    if (presentationService.isInLayover(currentVehicleTripStatus)) {
        progressStatuses.add("layover");
    }
    // "prevTrip" really means not on the framedvehiclejourney trip
    if (!framedJourneyTripBean.getId().equals(currentVehicleTripStatus.getActiveTrip().getId())) {
        progressStatuses.add("prevTrip");
    }
    if (!progressStatuses.isEmpty()) {
        NaturalLanguageStringStructure progressStatus = new NaturalLanguageStringStructure();
        progressStatus.setValue(StringUtils.join(progressStatuses, ","));
        monitoredVehicleJourney.setProgressStatus(progressStatus);
    }
    // block ref
    if (presentationService.isBlockLevelInference(currentVehicleTripStatus)) {
        BlockRefStructure blockRef = new BlockRefStructure();
        blockRef.setValue(framedJourneyTripBean.getBlockId());
        monitoredVehicleJourney.setBlockRef(blockRef);
    }
    // scheduled depature time
    if (presentationService.isBlockLevelInference(currentVehicleTripStatus) && (presentationService.isInLayover(currentVehicleTripStatus) || !framedJourneyTripBean.getId().equals(currentVehicleTripStatus.getActiveTrip().getId()))) {
        BlockStopTimeBean originDepartureStopTime = null;
        for (int t = 0; t < blockTrips.size(); t++) {
            BlockTripBean thisTrip = blockTrips.get(t);
            BlockTripBean nextTrip = null;
            if (t + 1 < blockTrips.size()) {
                nextTrip = blockTrips.get(t + 1);
            }
            if (thisTrip.getTrip().getId().equals(currentVehicleTripStatus.getActiveTrip().getId())) {
                // just started new trip
                if (currentVehicleTripStatus.getDistanceAlongTrip() < (0.5 * currentVehicleTripStatus.getTotalDistanceAlongTrip())) {
                    originDepartureStopTime = thisTrip.getBlockStopTimes().get(0);
                // at end of previous trip
                } else {
                    if (nextTrip != null) {
                        originDepartureStopTime = nextTrip.getBlockStopTimes().get(0);
                    }
                }
                break;
            }
        }
        if (originDepartureStopTime != null) {
            Date departureTime = new Date(currentVehicleTripStatus.getServiceDate() + (originDepartureStopTime.getStopTime().getDepartureTime() * 1000));
            monitoredVehicleJourney.setOriginAimedDepartureTime(departureTime);
        }
    }
    Map<String, TimepointPredictionRecord> stopIdToPredictionRecordMap = new HashMap<String, TimepointPredictionRecord>();
    // (build map of vehicle IDs to TPRs)
    if (stopLevelPredictions != null) {
        for (TimepointPredictionRecord tpr : stopLevelPredictions) {
            stopIdToPredictionRecordMap.put(AgencyAndId.convertToString(tpr.getTimepointId()), tpr);
        }
    }
    // monitored call
    if (!presentationService.isOnDetour(currentVehicleTripStatus))
        fillMonitoredCall(monitoredVehicleJourney, blockInstance, currentVehicleTripStatus, monitoredCallStopBean, presentationService, transitDataService, stopIdToPredictionRecordMap, hasRealtimeData, responseTimestamp);
    // onward calls
    if (!presentationService.isOnDetour(currentVehicleTripStatus))
        fillOnwardCalls(monitoredVehicleJourney, blockInstance, framedJourneyTripBean, currentVehicleTripStatus, onwardCallsMode, presentationService, transitDataService, stopIdToPredictionRecordMap, maximumOnwardCalls, hasRealtimeData, responseTimestamp);
    // situations
    fillSituations(monitoredVehicleJourney, currentVehicleTripStatus);
    return;
}
Also used : NaturalLanguageStringStructure(uk.org.siri.siri.NaturalLanguageStringStructure) BlockTripBean(org.onebusaway.transit_data.model.blocks.BlockTripBean) DestinationRefStructure(uk.org.siri.siri.DestinationRefStructure) HashMap(java.util.HashMap) DecimalFormat(java.text.DecimalFormat) ArrayList(java.util.ArrayList) LocationStructure(uk.org.siri.siri.LocationStructure) BlockStopTimeBean(org.onebusaway.transit_data.model.blocks.BlockStopTimeBean) DataFrameRefStructure(uk.org.siri.siri.DataFrameRefStructure) OperatorRefStructure(uk.org.siri.siri.OperatorRefStructure) JourneyPlaceRefStructure(uk.org.siri.siri.JourneyPlaceRefStructure) FramedVehicleJourneyRefStructure(uk.org.siri.siri.FramedVehicleJourneyRefStructure) JourneyPatternRefStructure(uk.org.siri.siri.JourneyPatternRefStructure) BlockRefStructure(uk.org.siri.siri.BlockRefStructure) LineRefStructure(uk.org.siri.siri.LineRefStructure) BigDecimal(java.math.BigDecimal) Date(java.util.Date) BlockInstanceBean(org.onebusaway.transit_data.model.blocks.BlockInstanceBean) TimepointPredictionRecord(org.onebusaway.realtime.api.TimepointPredictionRecord) StopBean(org.onebusaway.transit_data.model.StopBean) DirectionRefStructure(uk.org.siri.siri.DirectionRefStructure) VehicleRefStructure(uk.org.siri.siri.VehicleRefStructure)

Example 12 with TimepointPredictionRecord

use of org.onebusaway.realtime.api.TimepointPredictionRecord in project onebusaway-application-modules by camsys.

the class ArrivalAndDepartureServiceImplTest method testGetArrivalsAndDeparturesForStopInTimeRange01.

/**
 * This method tests time point predictions upstream of a stop for *arrival*
 * times.
 *
 * Test configuration: Time point predictions are upstream of the stop and
 * include the given stop_ids, which means that the bus hasn't passed these
 * bus stops yet. There are 2 bus stops which have the real time arrival times
 * (time point predictions). In this case
 * getArrivalsAndDeparturesForStopInTimeRange() should return the absolute
 * time point prediction for particular stop that was provided by the feed,
 * which replaces the scheduled time from GTFS for these stops.
 *
 * Current time = 13:00
 *        Schedule time    Real-time from feed
 * Stop A 13:30            13:30
 * Stop B 13:40            13:50
 *
 * When requesting arrival estimate for Stop B, result should be 13:50 (same
 * as exact prediction from real-time feed).
 */
@Test
public void testGetArrivalsAndDeparturesForStopInTimeRange01() {
    // Set time point predictions for stop A
    TimepointPredictionRecord tprA = new TimepointPredictionRecord();
    tprA.setTimepointId(mStopA.getId());
    long tprATime = createPredictedTime(time(13, 30));
    tprA.setTimepointPredictedArrivalTime(tprATime);
    tprA.setTripId(mTrip1.getId());
    // Set time point predictions for stop B
    TimepointPredictionRecord tprB = new TimepointPredictionRecord();
    tprB.setTimepointId(mStopB.getId());
    long tprBTime = createPredictedTime(time(13, 50));
    tprB.setTimepointPredictedArrivalTime(tprBTime);
    tprB.setTripId(mTrip1.getId());
    // Call ArrivalsAndDeparturesForStopInTimeRange method in
    // ArrivalAndDepartureServiceImpl
    List<ArrivalAndDepartureInstance> arrivalsAndDepartures = getArrivalsAndDeparturesForStopInTimeRangeByTimepointPredictionRecord(Arrays.asList(tprA, tprB));
    long predictedArrivalTime = getPredictedArrivalTimeByStopId(arrivalsAndDepartures, mStopB.getId());
    /**
     * Check if the predictedArrivalTime is exactly the same as the
     * TimepointPrediction.
     */
    assertEquals(tprB.getTimepointPredictedArrivalTime(), predictedArrivalTime);
}
Also used : TimepointPredictionRecord(org.onebusaway.realtime.api.TimepointPredictionRecord) ArrivalAndDepartureInstance(org.onebusaway.transit_data_federation.services.realtime.ArrivalAndDepartureInstance) Test(org.junit.Test)

Example 13 with TimepointPredictionRecord

use of org.onebusaway.realtime.api.TimepointPredictionRecord in project onebusaway-application-modules by camsys.

the class ArrivalAndDepartureServiceImplTest method testGetArrivalsAndDeparturesForStopInTimeRange17.

/**
 * This method tests loops in the middle of routes (the same stop is visited more
 * than once in the same trip) when stop_sequence is missing in the real-time feed.
 * It attempts to apply the prediction if there is more than one prediction in the
 * same trip (i.e., the stop_id can be disambiguated).  However, there is a limitation for
 * when the loop is in the middle of the trip (see FIXME below) - in this case, we can't disambiguate
 * the time point prediction without stop_sequence.  In other cases (and tests in this class),
 * we are able to disambiguate the predictions for simple loop trips when the prediction is
 * for the first or last stop in the trip and the first and last stop are the same, and we are able
 * to infer this from the presence of more than one prediction (see #163).  However, we can't
 * currently make this same inference for loops that occur in middle of the route, as it would require
 * us to look at a larger window of stops, which increases the computation time overhead.  We would also
 * need to add some bundle build-time attributes to identify which trips have loops within them,
 * and which stops are the loop stops that appear more than once.
 *
 * NOTE: The "real" and simplest fix for this issue is for the real-time feed to include stop_sequence
 * to disambiguate which real-time prediction should apply to which stop.  This isn't currently a
 * requirement in GTFS-rt, but we're trying to make it one (see https://github.com/google/transit/pull/20).
 *
 * Test configuration: There is one trip and this trip has 4 stops. But, in the middle of the route,
 * same stop B visited twice. So, the route look like this: A->B->C->B->D, where the stop B visited twice
 * in the middle of the route. Time point predictions do not have stop sequences,
 * and therefore the update for Stop B is ambiguous. We currently do not have any mechanism to handle
 * this case, and OBA cannot understand this is a loop route, because loop happens in
 * the middle of the route. OBA will currently (and erroneously) apply the real-time update for both stop Bs.
 * As a result, it will predict the arrival times wrong for stop b (sequence = 3) and stop D.
 *
 * Current time = 14:00
 *          Schedule time    Real-time from feed   GTFS stop_sequence  trip_id
 * Stop A   13:30            -----                          0           t1
 * Stop B   13:45            13:50                          1           t1
 * Stop C   13:55            -----                          2           t1
 * Stop B   14:05            -----                          3           t1
 * Stop D   14:15            -----                          4           t1
 */
@Test
public void testGetArrivalsAndDeparturesForStopInTimeRange17() {
    // Override the current time with a later time than the time point
    // predictions
    mCurrentTime = dateAsLong("2015-07-23 14:00");
    // Set time point prediction for trip 1 stop B
    TimepointPredictionRecord tpr1A = new TimepointPredictionRecord();
    tpr1A.setTimepointId(mStopB.getId());
    long tpr1ATime = createPredictedTime(time(13, 50));
    tpr1A.setTimepointPredictedArrivalTime(tpr1ATime);
    tpr1A.setTripId(mTrip1.getId());
    // Call ArrivalsAndDeparturesForStopInTimeRange method in
    // ArrivalAndDepartureServiceImpl
    List<ArrivalAndDepartureInstance> arrivalsAndDepartures = getArrivalsAndDeparturesForLoopInTheMiddleOfRouteInTimeRangeByTimepointPredictionRecord(Arrays.asList(tpr1A));
    // First trip in block
    long predictedArrivalTimeStop1A = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopA.getId(), mTrip1.getId(), 0);
    long predictedArrivalTimeStop1B = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopB.getId(), mTrip1.getId(), 1);
    long predictedArrivalTimeStop1C = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopC.getId(), mTrip1.getId(), 2);
    long predictedArrivalTimeStop1BB = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopB.getId(), mTrip1.getId(), 3);
    long predictedArrivalTimeStop1D = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopD.getId(), mTrip1.getId(), 4);
    /**
     * Make sure no real-time info is applied to stop A
     */
    assertEquals(predictedArrivalTimeStop1A, 0);
    /**
     * Check predictions for first stop B and stop C.  We should have correct predictions for these stops.
     */
    long scheduledArrivalTime1B = getScheduledArrivalTimeByStopId(mTrip1, mStopB.getId(), 1);
    long scheduledArrivalTime1C = getScheduledArrivalTimeByStopId(mTrip1, mStopC.getId(), 2);
    // Calculate the delay of the last stop A in trip B
    long delta = TimeUnit.MILLISECONDS.toSeconds(predictedArrivalTimeStop1B) - scheduledArrivalTime1B;
    assertEquals(predictedArrivalTimeStop1B, tpr1A.getTimepointPredictedArrivalTime());
    assertEquals(scheduledArrivalTime1C + delta, TimeUnit.MILLISECONDS.toSeconds(predictedArrivalTimeStop1C));
/**
 * FIXME: Properly apply real-time updates without stop_sequence to loop stops if they are in the middle of the trip
 *
 * In this test, we have a stop (stop B) and it is visited twice in the middle of the route.
 * We have only one timePointPredicition without stop_sequence for the first stop B. OBA currently
 * cannot determine this is a loop route. Therefore, it will apply the same timePointPrediction to
 * two different stops (the first stop B and the second stop B). The proper behavior would be for the
 * second visited stop B (stop_sequence = 3), we should have prediction propagated downstream from the
 *  first Stop B (stop_sequence = 1) (see below assertions for what should be happening).
 *
 * As a result, the following test cases should fail with the current configuration, and therefore are commented out.
 * A simple fix to solve this problem is for the provider to add stop_squence in the GTFS-realtime feed.
 */
// long scheduledArrivalTime1BB = getScheduledArrivalTimeByStopId(mTrip1,
// mStopB.getId(), 3);
// long scheduledArrivalTime1D = getScheduledArrivalTimeByStopId(mTrip1,
// mStopD.getId(), 4);
// 
// assertEquals(scheduledArrivalTime1BB + delta , TimeUnit.MILLISECONDS.toSeconds(predictedArrivalTimeStop1BB));
// assertEquals(scheduledArrivalTime1D + delta , TimeUnit.MILLISECONDS.toSeconds(predictedArrivalTimeStop1D));
}
Also used : TimepointPredictionRecord(org.onebusaway.realtime.api.TimepointPredictionRecord) ArrivalAndDepartureInstance(org.onebusaway.transit_data_federation.services.realtime.ArrivalAndDepartureInstance) Test(org.junit.Test)

Example 14 with TimepointPredictionRecord

use of org.onebusaway.realtime.api.TimepointPredictionRecord in project onebusaway-application-modules by camsys.

the class ArrivalAndDepartureServiceImplTest method testGetArrivalsAndDeparturesForStopInTimeRange02.

/**
 * This method tests upstream time point predictions for scheduled *arrival*
 * times.
 *
 * Test configuration: Time point predictions are upstream of the current
 * stop_id, which means that the bus hasn't passed the bus stop yet. A real
 * time arrival time (time point prediction) is provided for only one bus stop
 * (Stop A). In this case getArrivalsAndDeparturesForStopInTimeRange() should
 * calculate a new arrival time for Stop B (based on the upstream prediction
 * for Stop A), which is the scheduled arrival time + the upstream deviation.
 *
 * Current time = 13:00
 *          Schedule time    Real-time from feed
 * Stop A   13:30            13:35
 * Stop B   13:40            ---
 *
 * We are requesting arrival time for Stop B, which should be propagated
 * downstream from Stop A's prediction, which should be 13:45 (13:40 + 5 min
 * deviation from Stop A). Stop A's predicted arrival and departure should
 * also be the respective scheduled arrival and departure plus the 5 min
 * deviation.
 */
@Test
public void testGetArrivalsAndDeparturesForStopInTimeRange02() {
    // Set time point predictions for stop A
    TimepointPredictionRecord tprA = new TimepointPredictionRecord();
    tprA.setTimepointId(mStopA.getId());
    long tprATime = createPredictedTime(time(13, 35));
    tprA.setTimepointPredictedArrivalTime(tprATime);
    tprA.setTripId(mTrip1.getId());
    // Call ArrivalsAndDeparturesForStopInTimeRange method in
    // ArrivalAndDepartureServiceImpl
    List<ArrivalAndDepartureInstance> arrivalsAndDepartures = getArrivalsAndDeparturesForStopInTimeRangeByTimepointPredictionRecord(Arrays.asList(tprA));
    long predictedArrivalTimeStopA = getPredictedArrivalTimeByStopId(arrivalsAndDepartures, mStopA.getId());
    long predictedDepartureTimeStopA = getPredictedDepartureTimeByStopId(arrivalsAndDepartures, mStopA.getId());
    long predictedArrivalTimeStopB = getPredictedArrivalTimeByStopId(arrivalsAndDepartures, mStopB.getId());
    long predictedDepartureTimeStopB = getPredictedDepartureTimeByStopId(arrivalsAndDepartures, mStopB.getId());
    long scheduledArrivalTimeStopA = getScheduledArrivalTimeByStopId(mTrip1, mStopA.getId());
    long scheduledDepartureTimeStopA = getScheduledDepartureTimeByStopId(mTrip1, mStopA.getId());
    long scheduledArrivalTimeStopB = getScheduledArrivalTimeByStopId(mTrip1, mStopB.getId());
    long scheduledDepartureTimeStopB = getScheduledDepartureTimeByStopId(mTrip1, mStopB.getId());
    // The time point prediction for Stop A was 5 min late, so this should be
    // applied to Stop B scheduled arrival
    long delta = TimeUnit.MILLISECONDS.toSeconds(predictedArrivalTimeStopA) - scheduledArrivalTimeStopA;
    assertEquals(TimeUnit.MINUTES.toSeconds(5), delta);
    // Check if the predictedArrivalTimes and predictedDepartureTimes is the
    // same as the scheduledArrivalTime plus the delta
    assertEquals(TimeUnit.MILLISECONDS.toSeconds(predictedArrivalTimeStopA), scheduledArrivalTimeStopA + delta);
    assertEquals(TimeUnit.MILLISECONDS.toSeconds(predictedDepartureTimeStopA), scheduledDepartureTimeStopA + delta);
    assertEquals(TimeUnit.MILLISECONDS.toSeconds(predictedArrivalTimeStopB), scheduledArrivalTimeStopB + delta);
    assertEquals(TimeUnit.MILLISECONDS.toSeconds(predictedDepartureTimeStopB), scheduledDepartureTimeStopB + delta);
}
Also used : TimepointPredictionRecord(org.onebusaway.realtime.api.TimepointPredictionRecord) ArrivalAndDepartureInstance(org.onebusaway.transit_data_federation.services.realtime.ArrivalAndDepartureInstance) Test(org.junit.Test)

Example 15 with TimepointPredictionRecord

use of org.onebusaway.realtime.api.TimepointPredictionRecord in project onebusaway-application-modules by camsys.

the class ArrivalAndDepartureServiceImplTest method testGetArrivalsAndDeparturesForStopInTimeRange11.

/**
 * This method tests loop routes (the same stop is visited more
 * than once in the same trip) when stop_sequence is missing in the real-time feed.
 * It applies the prediction if there is more than one prediction in the same trip
 * (i.e., the stop_id can be disambiguated).
 *
 * Test configuration: There are three different loop trips in the same block
 * and each trip has 3 stops.  Time point predictions do not have stop_sequences.
 * Last 2 stops in middle trip have predictions.
 *
 * Current time = 14:00
 *          Schedule time    Real-time from feed      GTFS stop_sequence  trip_id
 * Stop A   13:30            -----                          0           t1
 * Stop B   13:45            -----                          1           t1
 * Stop A   13:55            -----                          2           t1
 *
 * Stop A   14:05            -----                          0             t2
 * Stop B   14:15            14:25                          1           t2
 * Stop A   14:25            14:35                          2             t2
 *
 * Stop A   14:30            -----                          0           t3
 * Stop B   14:45            -----                          1           t3
 * Stop A   14:55            -----                          2           t3
 */
@Test
public void testGetArrivalsAndDeparturesForStopInTimeRange11() {
    // Override the current time with a later time than the time point
    // predictions
    mCurrentTime = dateAsLong("2015-07-23 14:00");
    // Set time point predictions for trip 2 stop B
    TimepointPredictionRecord tprB = new TimepointPredictionRecord();
    tprB.setTimepointId(mStopB.getId());
    long tprBTime = createPredictedTime(time(14, 25));
    tprB.setTimepointPredictedArrivalTime(tprBTime);
    tprB.setTripId(mTrip2.getId());
    // Set time point predictions for trip 3 stop A (last instance)
    TimepointPredictionRecord tprA = new TimepointPredictionRecord();
    tprA.setTimepointId(mStopA.getId());
    long tprATime = createPredictedTime(time(14, 35));
    tprA.setTimepointPredictedArrivalTime(tprATime);
    tprA.setTripId(mTrip2.getId());
    // Call ArrivalsAndDeparturesForStopInTimeRange method in
    // ArrivalAndDepartureServiceImpl
    List<ArrivalAndDepartureInstance> arrivalsAndDepartures = getArrivalsAndDeparturesForLoopRouteInTimeRangeByTimepointPredictionRecordWithMultipleTrips(Arrays.asList(tprB, tprA), mStopB);
    // First trip in block
    long predictedArrivalTimeStop1A = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopA.getId(), mTrip1.getId(), 0);
    long predictedArrivalTimeStop1B = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopB.getId(), mTrip1.getId(), 1);
    long predictedArrivalTimeStop1C = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopA.getId(), mTrip1.getId(), 2);
    assertEquals(predictedArrivalTimeStop1A, 0);
    assertEquals(predictedArrivalTimeStop1B, 0);
    assertEquals(predictedArrivalTimeStop1C, 0);
    // Second trip in block
    long predictedArrivalTimeStop2A = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopA.getId(), mTrip2.getId(), 0);
    assertEquals(predictedArrivalTimeStop2A, 0);
    /**
     * Make sure the predictedArrivalTime for stop B and stop A (the last stop) in
     * the trip B is exactly the same as TimepointPredictionRecords.
     */
    long predictedArrivalTime2B = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopB.getId(), mTrip2.getId(), 1);
    long predictedArrivalTime2C = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopA.getId(), mTrip2.getId(), 2);
    assertEquals(tprB.getTimepointPredictedArrivalTime(), predictedArrivalTime2B);
    assertEquals(tprA.getTimepointPredictedArrivalTime(), predictedArrivalTime2C);
    /**
     * Make sure the predictions happening downstream based on the last stop
     * of the trip B
     */
    long scheduledArrivalTime2C = getScheduledArrivalTimeByStopId(mTrip2, mStopA.getId(), 2);
    // Calculate the delay of the last stop A in trip B
    long delta = TimeUnit.MILLISECONDS.toSeconds(predictedArrivalTime2C) - scheduledArrivalTime2C;
    // Third trip in block
    long scheduledArrivalTimeStop3A = getScheduledArrivalTimeByStopId(mTrip3, mStopA.getId(), 0);
    long predictedArrivalTime3A = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopA.getId(), mTrip3.getId(), 0);
    long scheduledArrivalTimeStop3B = getScheduledArrivalTimeByStopId(mTrip3, mStopB.getId(), 1);
    long predictedArrivalTime3B = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopB.getId(), mTrip3.getId(), 1);
    long scheduledArrivalTimeStop3C = getScheduledArrivalTimeByStopId(mTrip3, mStopA.getId(), 2);
    long predictedArrivalTime3C = getPredictedArrivalTimeByStopIdAndSequence(arrivalsAndDepartures, mStopA.getId(), mTrip3.getId(), 2);
    assertEquals(scheduledArrivalTimeStop3A + delta, TimeUnit.MILLISECONDS.toSeconds(predictedArrivalTime3A));
    assertEquals(scheduledArrivalTimeStop3B + delta, TimeUnit.MILLISECONDS.toSeconds(predictedArrivalTime3B));
    assertEquals(scheduledArrivalTimeStop3C + delta, TimeUnit.MILLISECONDS.toSeconds(predictedArrivalTime3C));
}
Also used : TimepointPredictionRecord(org.onebusaway.realtime.api.TimepointPredictionRecord) ArrivalAndDepartureInstance(org.onebusaway.transit_data_federation.services.realtime.ArrivalAndDepartureInstance) Test(org.junit.Test)

Aggregations

TimepointPredictionRecord (org.onebusaway.realtime.api.TimepointPredictionRecord)36 Test (org.junit.Test)20 ArrivalAndDepartureInstance (org.onebusaway.transit_data_federation.services.realtime.ArrivalAndDepartureInstance)17 ArrayList (java.util.ArrayList)10 Date (java.util.Date)6 AgencyAndId (org.onebusaway.gtfs.model.AgencyAndId)6 BlockInstance (org.onebusaway.transit_data_federation.services.blocks.BlockInstance)6 BlockConfigurationEntry (org.onebusaway.transit_data_federation.services.transit_graph.BlockConfigurationEntry)6 StopTimeUpdate (com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate)5 TripUpdate (com.google.transit.realtime.GtfsRealtime.TripUpdate)4 VehicleLocationRecord (org.onebusaway.realtime.api.VehicleLocationRecord)4 TripDetailsBean (org.onebusaway.transit_data.model.trips.TripDetailsBean)4 BlockStopTimeEntry (org.onebusaway.transit_data_federation.services.transit_graph.BlockStopTimeEntry)4 StopTimeEntry (org.onebusaway.transit_data_federation.services.transit_graph.StopTimeEntry)4 StopTimeEvent (com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeEvent)3 HashMap (java.util.HashMap)3 StopBean (org.onebusaway.transit_data.model.StopBean)3 TripBean (org.onebusaway.transit_data.model.trips.TripBean)3 TripStatusBean (org.onebusaway.transit_data.model.trips.TripStatusBean)3 BlockEntryImpl (org.onebusaway.transit_data_federation.impl.transit_graph.BlockEntryImpl)3