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;
}
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;
}
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());
}
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();
}
}
Aggregations