Search in sources :

Example 6 with EstimatedVehicleJourney

use of uk.org.siri.siri20.EstimatedVehicleJourney in project OpenTripPlanner by opentripplanner.

the class TimetableHelper method createModifiedStopTimes.

/**
 * Apply the SIRI ET to the appropriate TripTimes from this Timetable.
 * Calculate new stoppattern based on single stop cancellations
 *
 * @param journey    SIRI-ET EstimatedVehicleJourney
 * @return new copy of updated TripTimes after TripUpdate has been applied on TripTimes of trip
 * with the id specified in the trip descriptor of the TripUpdate; null if something
 * went wrong
 */
public static List<StopTime> createModifiedStopTimes(Timetable timetable, TripTimes oldTimes, EstimatedVehicleJourney journey, Trip trip, RoutingService routingService) {
    if (journey == null) {
        return null;
    }
    List<EstimatedCall> estimatedCalls;
    List<RecordedCall> recordedCalls;
    if (journey.getEstimatedCalls() != null) {
        estimatedCalls = journey.getEstimatedCalls().getEstimatedCalls();
    } else {
        estimatedCalls = EMPTY_LIST;
    }
    if (journey.getRecordedCalls() != null) {
        recordedCalls = journey.getRecordedCalls().getRecordedCalls();
    } else {
        recordedCalls = EMPTY_LIST;
    }
    var stops = createModifiedStops(timetable, journey, routingService);
    List<StopTime> modifiedStops = new ArrayList<>();
    ZonedDateTime departureDate = null;
    int numberOfRecordedCalls = (journey.getRecordedCalls() != null && journey.getRecordedCalls().getRecordedCalls() != null) ? journey.getRecordedCalls().getRecordedCalls().size() : 0;
    Set<Object> alreadyVisited = new HashSet<>();
    // modify updated stop-times
    for (int i = 0; i < stops.size(); i++) {
        StopLocation stop = stops.get(i);
        final StopTime stopTime = new StopTime();
        stopTime.setStop(stop);
        stopTime.setTrip(trip);
        stopTime.setStopSequence(i);
        stopTime.setDropOffType(timetable.getPattern().getAlightType(i));
        stopTime.setPickupType(timetable.getPattern().getBoardType(i));
        stopTime.setArrivalTime(oldTimes.getScheduledArrivalTime(i));
        stopTime.setDepartureTime(oldTimes.getScheduledDepartureTime(i));
        stopTime.setStopHeadsign(oldTimes.getHeadsign(i));
        // TODO: Do we need to set the StopTime.id?
        // stopTime.setId(oldTimes.getStopTimeIdByIndex(i));
        boolean foundMatch = false;
        if (i < numberOfRecordedCalls) {
            for (RecordedCall recordedCall : recordedCalls) {
                if (alreadyVisited.contains(recordedCall)) {
                    continue;
                }
                // Current stop is being updated
                var callStopRef = recordedCall.getStopPointRef().getValue();
                boolean stopsMatchById = stop.getId().getId().equals(callStopRef);
                if (!stopsMatchById && stop.isPartOfStation()) {
                    var alternativeStop = routingService.getStopForId(new FeedScopedId(stop.getId().getFeedId(), callStopRef));
                    if (alternativeStop != null && stop.isPartOfSameStationAs(alternativeStop)) {
                        stopsMatchById = true;
                        stopTime.setStop(alternativeStop);
                    }
                }
                if (stopsMatchById) {
                    foundMatch = true;
                    if (recordedCall.isCancellation() != null && recordedCall.isCancellation()) {
                        stopTime.cancel();
                    }
                    modifiedStops.add(stopTime);
                    alreadyVisited.add(recordedCall);
                    break;
                }
            }
        } else {
            for (EstimatedCall estimatedCall : estimatedCalls) {
                if (alreadyVisited.contains(estimatedCall)) {
                    continue;
                }
                if (departureDate == null) {
                    departureDate = (estimatedCall.getAimedDepartureTime() != null ? estimatedCall.getAimedDepartureTime() : estimatedCall.getAimedArrivalTime());
                }
                // Current stop is being updated
                boolean stopsMatchById = stop.getId().getId().equals(estimatedCall.getStopPointRef().getValue());
                if (!stopsMatchById && stop.isPartOfStation()) {
                    var alternativeStop = routingService.getStopForId(new FeedScopedId(stop.getId().getFeedId(), estimatedCall.getStopPointRef().getValue()));
                    if (alternativeStop != null && stop.isPartOfSameStationAs(alternativeStop)) {
                        stopsMatchById = true;
                        stopTime.setStop(alternativeStop);
                    }
                }
                if (stopsMatchById) {
                    foundMatch = true;
                    CallStatusEnumeration arrivalStatus = estimatedCall.getArrivalStatus();
                    if (arrivalStatus == CallStatusEnumeration.CANCELLED) {
                        stopTime.cancelDropOff();
                    } else if (estimatedCall.getArrivalBoardingActivity() == ArrivalBoardingActivityEnumeration.ALIGHTING) {
                        stopTime.setDropOffType(SCHEDULED);
                    } else if (estimatedCall.getArrivalBoardingActivity() == ArrivalBoardingActivityEnumeration.NO_ALIGHTING) {
                        stopTime.setDropOffType(NONE);
                    } else if (estimatedCall.getArrivalBoardingActivity() == null && i == 0) {
                        // First stop - default no dropoff
                        stopTime.setDropOffType(NONE);
                    }
                    CallStatusEnumeration departureStatus = estimatedCall.getDepartureStatus();
                    if (departureStatus == CallStatusEnumeration.CANCELLED) {
                        stopTime.cancelPickup();
                    } else if (estimatedCall.getDepartureBoardingActivity() == DepartureBoardingActivityEnumeration.BOARDING) {
                        stopTime.setPickupType(SCHEDULED);
                    } else if (estimatedCall.getDepartureBoardingActivity() == DepartureBoardingActivityEnumeration.NO_BOARDING) {
                        stopTime.setPickupType(NONE);
                    } else if (estimatedCall.getDepartureBoardingActivity() == null && i == (stops.size() - 1)) {
                        // Last stop - default no pickup
                        stopTime.setPickupType(NONE);
                    }
                    if (estimatedCall.isCancellation() != null && estimatedCall.isCancellation()) {
                        stopTime.cancel();
                    }
                    if (estimatedCall.getDestinationDisplaies() != null && !estimatedCall.getDestinationDisplaies().isEmpty()) {
                        NaturalLanguageStringStructure destinationDisplay = estimatedCall.getDestinationDisplaies().get(0);
                        stopTime.setStopHeadsign(destinationDisplay.getValue());
                    }
                    modifiedStops.add(stopTime);
                    alreadyVisited.add(estimatedCall);
                    break;
                }
            }
        }
        if (!foundMatch) {
            modifiedStops.add(stopTime);
        }
    }
    return modifiedStops;
}
Also used : NaturalLanguageStringStructure(uk.org.siri.siri20.NaturalLanguageStringStructure) ArrayList(java.util.ArrayList) RecordedCall(uk.org.siri.siri20.RecordedCall) ZonedDateTime(java.time.ZonedDateTime) FeedScopedId(org.opentripplanner.model.FeedScopedId) EstimatedCall(uk.org.siri.siri20.EstimatedCall) StopLocation(org.opentripplanner.model.StopLocation) CallStatusEnumeration(uk.org.siri.siri20.CallStatusEnumeration) StopTime(org.opentripplanner.model.StopTime) HashSet(java.util.HashSet)

Example 7 with EstimatedVehicleJourney

use of uk.org.siri.siri20.EstimatedVehicleJourney in project OpenTripPlanner by opentripplanner.

the class SiriTimetableSnapshotSource method getPatternForTrip.

private TripPattern getPatternForTrip(Trip trip, EstimatedVehicleJourney journey) {
    Set<ServiceDate> serviceDates = routingService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId());
    List<RecordedCall> recordedCalls = (journey.getRecordedCalls() != null ? journey.getRecordedCalls().getRecordedCalls() : new ArrayList<>());
    List<EstimatedCall> estimatedCalls;
    if (journey.getEstimatedCalls() != null) {
        estimatedCalls = journey.getEstimatedCalls().getEstimatedCalls();
    } else {
        return null;
    }
    String journeyFirstStopId;
    String journeyLastStopId;
    ServiceDate journeyDate;
    // Resolve first stop - check recordedCalls, then estimatedCalls
    if (recordedCalls != null && !recordedCalls.isEmpty()) {
        RecordedCall recordedCall = recordedCalls.get(0);
        journeyFirstStopId = recordedCall.getStopPointRef().getValue();
        journeyDate = new ServiceDate(Date.from(recordedCall.getAimedDepartureTime().toInstant()));
    } else if (estimatedCalls != null && !estimatedCalls.isEmpty()) {
        EstimatedCall estimatedCall = estimatedCalls.get(0);
        journeyFirstStopId = estimatedCall.getStopPointRef().getValue();
        journeyDate = new ServiceDate(Date.from(estimatedCall.getAimedDepartureTime().toInstant()));
    } else {
        return null;
    }
    // Resolve last stop - check estimatedCalls, then recordedCalls
    if (estimatedCalls != null && !estimatedCalls.isEmpty()) {
        EstimatedCall estimatedCall = estimatedCalls.get(estimatedCalls.size() - 1);
        journeyLastStopId = estimatedCall.getStopPointRef().getValue();
    } else if (recordedCalls != null && !recordedCalls.isEmpty()) {
        RecordedCall recordedCall = recordedCalls.get(recordedCalls.size() - 1);
        journeyLastStopId = recordedCall.getStopPointRef().getValue();
    } else {
        return null;
    }
    TripPattern lastAddedTripPattern = null;
    if (getTimetableSnapshot() != null) {
        lastAddedTripPattern = getTimetableSnapshot().getLastAddedTripPattern(trip.getId(), journeyDate);
    }
    TripPattern tripPattern;
    if (lastAddedTripPattern != null) {
        tripPattern = lastAddedTripPattern;
    } else {
        tripPattern = routingService.getPatternForTrip().get(trip);
    }
    var firstStop = tripPattern.firstStop();
    var lastStop = tripPattern.lastStop();
    if (serviceDates.contains(journeyDate)) {
        boolean firstStopIsMatch = firstStop.getId().getId().equals(journeyFirstStopId);
        boolean lastStopIsMatch = lastStop.getId().getId().equals(journeyLastStopId);
        if (!firstStopIsMatch && firstStop.isPartOfStation()) {
            var otherFirstStop = routingService.getStopForId(new FeedScopedId(firstStop.getId().getFeedId(), journeyFirstStopId));
            firstStopIsMatch = firstStop.isPartOfSameStationAs(otherFirstStop);
        }
        if (!lastStopIsMatch && lastStop.isPartOfStation()) {
            var otherLastStop = routingService.getStopForId(new FeedScopedId(lastStop.getId().getFeedId(), journeyLastStopId));
            lastStopIsMatch = lastStop.isPartOfSameStationAs(otherLastStop);
        }
        if (firstStopIsMatch & lastStopIsMatch) {
            // Found matches
            return tripPattern;
        }
        return null;
    }
    return null;
}
Also used : ServiceDate(org.opentripplanner.model.calendar.ServiceDate) ArrayList(java.util.ArrayList) FeedScopedId(org.opentripplanner.model.FeedScopedId) RecordedCall(uk.org.siri.siri20.RecordedCall) EstimatedCall(uk.org.siri.siri20.EstimatedCall) TripPattern(org.opentripplanner.model.TripPattern)

Example 8 with EstimatedVehicleJourney

use of uk.org.siri.siri20.EstimatedVehicleJourney in project OpenTripPlanner by opentripplanner.

the class SiriTimetableSnapshotSource method getServiceDateForEstimatedVehicleJourney.

private ServiceDate getServiceDateForEstimatedVehicleJourney(EstimatedVehicleJourney estimatedVehicleJourney) {
    ZonedDateTime date;
    if (estimatedVehicleJourney.getRecordedCalls() != null && !estimatedVehicleJourney.getRecordedCalls().getRecordedCalls().isEmpty()) {
        date = estimatedVehicleJourney.getRecordedCalls().getRecordedCalls().get(0).getAimedDepartureTime();
    } else {
        EstimatedCall firstCall = estimatedVehicleJourney.getEstimatedCalls().getEstimatedCalls().get(0);
        date = firstCall.getAimedDepartureTime();
    }
    if (date == null) {
        return null;
    }
    return new ServiceDate(date.getYear(), date.getMonthValue(), date.getDayOfMonth());
}
Also used : ServiceDate(org.opentripplanner.model.calendar.ServiceDate) ZonedDateTime(java.time.ZonedDateTime) EstimatedCall(uk.org.siri.siri20.EstimatedCall)

Example 9 with EstimatedVehicleJourney

use of uk.org.siri.siri20.EstimatedVehicleJourney in project OpenTripPlanner by opentripplanner.

the class SiriTimetableSnapshotSource method applyEstimatedTimetable.

/**
 * Method to apply a trip update list to the most recent version of the timetable snapshot.
 *
 *  @param graph graph to update (needed for adding/changing stop patterns)
 * @param fullDataset true iff the list with updates represent all updates that are active right
 *        now, i.e. all previous updates should be disregarded
 * @param updates SIRI VehicleMonitoringDeliveries that should be applied atomically
 */
public void applyEstimatedTimetable(final Graph graph, final String feedId, final boolean fullDataset, final List<EstimatedTimetableDeliveryStructure> updates) {
    if (updates == null) {
        LOG.warn("updates is null");
        return;
    }
    // Acquire lock on buffer
    bufferLock.lock();
    try {
        if (fullDataset) {
            // Remove all updates from the buffer
            buffer.clear(feedId);
        }
        for (EstimatedTimetableDeliveryStructure etDelivery : updates) {
            List<EstimatedVersionFrameStructure> estimatedJourneyVersions = etDelivery.getEstimatedJourneyVersionFrames();
            if (estimatedJourneyVersions != null) {
                // Handle deliveries
                for (EstimatedVersionFrameStructure estimatedJourneyVersion : estimatedJourneyVersions) {
                    List<EstimatedVehicleJourney> journeys = estimatedJourneyVersion.getEstimatedVehicleJourneies();
                    LOG.debug("Handling {} EstimatedVehicleJourneys.", journeys.size());
                    int handledCounter = 0;
                    int skippedCounter = 0;
                    int addedCounter = 0;
                    int notMonitoredCounter = 0;
                    for (EstimatedVehicleJourney journey : journeys) {
                        if (journey.isExtraJourney() != null && journey.isExtraJourney()) {
                            // Added trip
                            try {
                                if (handleAddedTrip(graph, feedId, journey)) {
                                    addedCounter++;
                                } else {
                                    skippedCounter++;
                                }
                            } catch (Throwable t) {
                                // Since this is work in progress - catch everything to continue processing updates
                                LOG.warn("Adding ExtraJourney with id='{}' failed, caused by '{}'.", journey.getEstimatedVehicleJourneyCode(), t.getMessage());
                                skippedCounter++;
                            }
                        } else {
                            // Updated trip
                            if (handleModifiedTrip(graph, feedId, journey)) {
                                handledCounter++;
                            } else {
                                if (journey.isMonitored() != null && !journey.isMonitored()) {
                                    notMonitoredCounter++;
                                } else {
                                    skippedCounter++;
                                }
                            }
                        }
                    }
                    LOG.debug("Processed EstimatedVehicleJourneys: updated {}, added {}, skipped {}, not monitored {}.", handledCounter, addedCounter, skippedCounter, notMonitoredCounter);
                }
            }
        }
        LOG.debug("message contains {} trip updates", updates.size());
        LOG.debug("end of update message");
        // Make sure that the public (locking) getTimetableSnapshot function is not called.
        if (purgeExpiredData) {
            final boolean modified = purgeExpiredData();
            getTimetableSnapshot(modified);
        } else {
            getTimetableSnapshot(false);
        }
    } finally {
        // Always release lock
        bufferLock.unlock();
    }
}
Also used : EstimatedVehicleJourney(uk.org.siri.siri20.EstimatedVehicleJourney) EstimatedVersionFrameStructure(uk.org.siri.siri20.EstimatedVersionFrameStructure) EstimatedTimetableDeliveryStructure(uk.org.siri.siri20.EstimatedTimetableDeliveryStructure)

Aggregations

EstimatedCall (uk.org.siri.siri20.EstimatedCall)8 RecordedCall (uk.org.siri.siri20.RecordedCall)7 ZonedDateTime (java.time.ZonedDateTime)6 ArrayList (java.util.ArrayList)6 FeedScopedId (org.opentripplanner.model.FeedScopedId)6 HashSet (java.util.HashSet)4 Trip (org.opentripplanner.model.Trip)4 ServiceDate (org.opentripplanner.model.calendar.ServiceDate)4 EstimatedVehicleJourney (uk.org.siri.siri20.EstimatedVehicleJourney)4 StopLocation (org.opentripplanner.model.StopLocation)3 StopTime (org.opentripplanner.model.StopTime)3 TripPattern (org.opentripplanner.model.TripPattern)3 TripTimes (org.opentripplanner.routing.trippattern.TripTimes)3 List (java.util.List)2 TimetableHelper.createUpdatedTripTimes (org.opentripplanner.ext.siri.TimetableHelper.createUpdatedTripTimes)2 RoutingService (org.opentripplanner.routing.RoutingService)2 CallStatusEnumeration (uk.org.siri.siri20.CallStatusEnumeration)2 NaturalLanguageStringStructure (uk.org.siri.siri20.NaturalLanguageStringStructure)2 Preconditions (com.google.common.base.Preconditions)1 ZoneId (java.time.ZoneId)1