use of uk.org.siri.siri20.VehicleActivityStructure in project OpenTripPlanner by opentripplanner.
the class TimetableHelper method createUpdatedTripTimes.
/**
* Apply the TripUpdate to the appropriate TripTimes from this Timetable. The existing TripTimes
* must not be modified directly because they may be shared with the underlying
* scheduledTimetable, or other updated Timetables. The {@link TimetableSnapshot} performs the
* protective copying of this Timetable. It is not done in this update method to avoid
* repeatedly cloning the same Timetable when several updates are applied to it at once. We
* assume here that all trips in a timetable are from the same feed, which should always be the
* case.
*
* @param activity SIRI-VM VehicleActivity
* @param timeZone time zone of trip update
* @param tripId
* @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 TripTimes createUpdatedTripTimes(Timetable timetable, Graph graph, VehicleActivityStructure activity, TimeZone timeZone, FeedScopedId tripId) {
if (activity == null) {
return null;
}
MonitoredVehicleJourneyStructure mvj = activity.getMonitoredVehicleJourney();
int tripIndex = timetable.getTripIndex(tripId);
if (tripIndex == -1) {
LOG.trace("tripId {} not found in pattern.", tripId);
return null;
}
final TripTimes existingTripTimes = timetable.getTripTimes(tripIndex);
TripTimes newTimes = new TripTimes(existingTripTimes);
MonitoredCallStructure update = mvj.getMonitoredCall();
if (update == null) {
return null;
}
final List<Stop> stops = timetable.pattern.getStops();
VehicleActivityStructure.MonitoredVehicleJourney monitoredVehicleJourney = activity.getMonitoredVehicleJourney();
Duration delay = null;
if (monitoredVehicleJourney != null) {
delay = monitoredVehicleJourney.getDelay();
int updatedDelay = 0;
if (delay != null) {
updatedDelay = delay.getSign() * (delay.getHours() * 3600 + delay.getMinutes() * 60 + delay.getSeconds());
}
MonitoredCallStructure monitoredCall = monitoredVehicleJourney.getMonitoredCall();
if (monitoredCall != null && monitoredCall.getStopPointRef() != null) {
boolean matchFound = false;
int arrivalDelay = 0;
int departureDelay = 0;
for (int index = 0; index < newTimes.getNumStops(); ++index) {
if (!matchFound) {
// Delay is set on a single stop at a time. When match is found - propagate delay on all following stops
final Stop stop = stops.get(index);
matchFound = stop.getId().getId().equals(monitoredCall.getStopPointRef().getValue());
if (!matchFound && stop.isPartOfStation()) {
FeedScopedId alternativeId = new FeedScopedId(stop.getId().getFeedId(), monitoredCall.getStopPointRef().getValue());
Stop alternativeStop = graph.index.getStopForId(alternativeId);
if (alternativeStop != null && alternativeStop.isPartOfStation()) {
matchFound = stop.isPartOfSameStationAs(alternativeStop);
}
}
if (matchFound) {
arrivalDelay = departureDelay = updatedDelay;
} else {
/*
* If updated delay is less than previously set delay, the existing delay needs to be adjusted to avoid
* non-increasing times causing updates to be rejected. Will only affect historical data.
*/
arrivalDelay = Math.min(existingTripTimes.getArrivalDelay(index), updatedDelay);
departureDelay = Math.min(existingTripTimes.getDepartureDelay(index), updatedDelay);
}
}
newTimes.updateArrivalDelay(index, arrivalDelay);
newTimes.updateDepartureDelay(index, departureDelay);
}
}
}
if (!newTimes.timesIncreasing()) {
LOG.info("TripTimes are non-increasing after applying SIRI delay propagation - delay: {}", delay);
return null;
}
// If state is already MODIFIED - keep existing state
if (newTimes.getRealTimeState() != RealTimeState.MODIFIED) {
// Make sure that updated trip times have the correct real time state
newTimes.setRealTimeState(RealTimeState.UPDATED);
}
return newTimes;
}
use of uk.org.siri.siri20.VehicleActivityStructure in project onebusaway-application-modules by camsys.
the class VehicleMonitoringV2Action method index.
public DefaultHttpHeaders index() throws IOException {
long currentTimestamp = getTime();
processGoogleAnalytics();
_realtimeService.setTime(currentTimestamp);
String detailLevelParam = _servletRequest.getParameter(VEHICLE_MONITORING_DETAIL_LEVEL);
// get the detail level parameter or set it to default if not specified
DetailLevel detailLevel;
if (DetailLevel.contains(detailLevelParam)) {
detailLevel = DetailLevel.valueOf(detailLevelParam.toUpperCase());
} else {
detailLevel = DetailLevel.NORMAL;
}
// User Parameters
String lineRef = _servletRequest.getParameter(LINE_REF);
String vehicleRef = _servletRequest.getParameter(VEHICLE_REF);
String directionId = _servletRequest.getParameter(DIRECTION_REF);
String agencyId = _servletRequest.getParameter(OPERATOR_REF);
String maxOnwardCallsParam = _servletRequest.getParameter(MAX_ONWARD_CALLS);
String maxStopVisitsParam = _servletRequest.getParameter(MAX_STOP_VISITS);
String minStopVisitsParam = _servletRequest.getParameter(MIN_STOP_VISITS);
// Error Strings
String routeIdsErrorString = "";
/*
* We need to support the user providing no agency id which means 'all agencies'.
So, this array will hold a single agency if the user provides it or all
agencies if the user provides none. We'll iterate over them later while
querying for vehicles and routes
*/
List<AgencyAndId> routeIds = new ArrayList<AgencyAndId>();
List<String> agencyIds = processAgencyIds(agencyId);
List<AgencyAndId> vehicleIds = processVehicleIds(vehicleRef, agencyIds);
routeIdsErrorString = processRouteIds(lineRef, routeIds, agencyIds);
int maximumOnwardCalls = 0;
if (detailLevel.equals(DetailLevel.CALLS)) {
maximumOnwardCalls = SiriSupportV2.convertToNumeric(maxOnwardCallsParam, Integer.MAX_VALUE);
}
String gaLabel = null;
// *** CASE 1: single vehicle, ignore any other filters
if (vehicleIds.size() > 0) {
gaLabel = vehicleRef;
List<VehicleActivityStructure> activities = new ArrayList<VehicleActivityStructure>();
try {
for (AgencyAndId vehicleId : vehicleIds) {
VehicleActivityStructure activity = _realtimeService.getVehicleActivityForVehicle(vehicleId.toString(), maximumOnwardCalls, detailLevel, currentTimestamp);
if (activity != null) {
activities.add(activity);
}
}
} catch (Exception e) {
_log.info(e.getMessage(), e);
}
// No vehicle id validation, so we pass null for error
_siriResponse = generateSiriResponse(activities, null, null, currentTimestamp);
// *** CASE 2: by route, using direction id, if provided
} else if (lineRef != null) {
gaLabel = lineRef;
List<VehicleActivityStructure> activities = new ArrayList<VehicleActivityStructure>();
for (AgencyAndId routeId : routeIds) {
List<VehicleActivityStructure> activitiesForRoute = _realtimeService.getVehicleActivityForRoute(routeId.toString(), directionId, maximumOnwardCalls, detailLevel, currentTimestamp);
if (activitiesForRoute != null) {
activities.addAll(activitiesForRoute);
}
}
if (vehicleIds.size() > 0) {
List<VehicleActivityStructure> filteredActivities = new ArrayList<VehicleActivityStructure>();
for (VehicleActivityStructure activity : activities) {
MonitoredVehicleJourneyStructure journey = activity.getMonitoredVehicleJourney();
AgencyAndId thisVehicleId = AgencyAndIdLibrary.convertFromString(journey.getVehicleRef().getValue());
// user filtering
if (!vehicleIds.contains(thisVehicleId))
continue;
filteredActivities.add(activity);
}
activities = filteredActivities;
}
Exception error = null;
if (lineRef != null && routeIds.size() == 0) {
error = new Exception(routeIdsErrorString.trim());
}
_siriResponse = generateSiriResponse(activities, routeIds, error, currentTimestamp);
// *** CASE 3: all vehicles
} else {
try {
gaLabel = "All Vehicles";
// int hashKey = _siriCacheService.hash(maximumOnwardCalls, agencyIds, _type);
List<VehicleActivityStructure> activities = new ArrayList<VehicleActivityStructure>();
// if (!_siriCacheService.containsKey(hashKey)) {
for (String agency : agencyIds) {
ListBean<VehicleStatusBean> vehicles = _transitDataService.getAllVehiclesForAgency(agency, currentTimestamp);
for (VehicleStatusBean v : vehicles.getList()) {
VehicleActivityStructure activity = _realtimeService.getVehicleActivityForVehicle(v.getVehicleId(), maximumOnwardCalls, detailLevel, currentTimestamp);
if (activity != null) {
activities.add(activity);
}
}
}
// There is no input (route id) to validate, so pass null error
_siriResponse = generateSiriResponse(activities, null, null, currentTimestamp);
// _siriCacheService.store(hashKey, getVehicleMonitoring());
// } else {
// _cachedResponse = _siriCacheService.retrieve(hashKey);
// }
} catch (Exception e) {
_log.error("vm all broke:", e);
throw new RuntimeException(e);
}
}
return setOkResponseText(getSiri());
}
use of uk.org.siri.siri20.VehicleActivityStructure in project onebusaway-application-modules by camsys.
the class ServiceAlertsHelperV2 method addSituationExchangeToServiceDelivery.
/*
public void addSituationExchangeToServiceDelivery(ServiceDelivery serviceDelivery,
List<VehicleActivityStructure> activities,
TransitDataService transitDataService) {
addSituationExchangeToServiceDelivery(serviceDelivery, activities, transitDataService, null);
}
*/
public void addSituationExchangeToServiceDelivery(ServiceDelivery serviceDelivery, List<VehicleActivityStructure> activities, TransitDataService transitDataService, List<AgencyAndId> routeIds) {
if (activities == null)
return;
Map<String, PtSituationElementStructure> ptSituationElements = new HashMap<String, PtSituationElementStructure>();
for (VehicleActivityStructure activity : activities) {
if (activity.getMonitoredVehicleJourney() != null) {
addSituationElement(transitDataService, ptSituationElements, activity.getMonitoredVehicleJourney().getSituationRef());
}
}
addPtSituationElementsToServiceDelivery(serviceDelivery, ptSituationElements);
if (routeIds == null)
return;
List<ServiceAlertBean> serviceAlerts = new ArrayList<ServiceAlertBean>();
for (AgencyAndId routeId : routeIds) {
SituationQueryBean query = new SituationQueryBean();
SituationQueryBean.AffectsBean affects = new SituationQueryBean.AffectsBean();
query.getAffects().add(affects);
affects.setRouteId(routeId.toString());
ListBean<ServiceAlertBean> serviceAlertsForRoute = transitDataService.getServiceAlerts(query);
// now query route + stop combinations
StopsForRouteBean stopsForRoute = transitDataService.getStopsForRoute(routeId.toString());
if (stopsForRoute != null) {
for (StopBean stopBean : stopsForRoute.getStops()) {
SituationQueryBean stopRouteQuery = new SituationQueryBean();
SituationQueryBean.AffectsBean stopRouteAffects = new SituationQueryBean.AffectsBean();
stopRouteQuery.getAffects().add(stopRouteAffects);
stopRouteAffects.setRouteId(routeId.toString());
stopRouteAffects.setStopId(stopBean.getId());
ListBean<ServiceAlertBean> serviceAlertsForRouteStop = transitDataService.getServiceAlerts(stopRouteQuery);
if (serviceAlertsForRouteStop != null)
serviceAlerts.addAll(serviceAlertsForRouteStop.getList());
}
}
if (serviceAlertsForRoute != null) {
serviceAlerts.addAll(serviceAlertsForRoute.getList());
}
}
if (serviceAlerts.size() == 0)
return;
addSituationExchangeToServiceDelivery(serviceDelivery, serviceAlerts);
}
use of uk.org.siri.siri20.VehicleActivityStructure in project onebusaway-application-modules by camsys.
the class RealtimeServiceV2Impl method getVehicleActivityForVehicle.
@Override
public VehicleActivityStructure getVehicleActivityForVehicle(String vehicleId, int maximumOnwardCalls, DetailLevel detailLevel, long currentTime) {
TripForVehicleQueryBean query = new TripForVehicleQueryBean();
query.setTime(new Date(currentTime));
query.setVehicleId(vehicleId);
TripDetailsInclusionBean inclusion = new TripDetailsInclusionBean();
inclusion.setIncludeTripStatus(true);
inclusion.setIncludeTripBean(true);
query.setInclusion(inclusion);
TripDetailsBean tripDetailsForCurrentTrip = _transitDataService.getTripDetailsForVehicleAndTime(query);
if (tripDetailsForCurrentTrip != null) {
if (!_presentationService.include(tripDetailsForCurrentTrip.getStatus()))
return null;
VehicleActivityStructure output = new VehicleActivityStructure();
output.setRecordedAtTime(DateUtil.toXmlGregorianCalendar(tripDetailsForCurrentTrip.getStatus().getLastUpdateTime()));
List<TimepointPredictionRecord> timePredictionRecords = null;
timePredictionRecords = _transitDataService.getPredictionRecordsForTrip(AgencyAndId.convertFromString(vehicleId).getAgencyId(), tripDetailsForCurrentTrip.getStatus());
boolean showApc = useApc();
if (!TransitDataConstants.STATUS_CANCELED.equals(tripDetailsForCurrentTrip.getStatus().getStatus())) {
output.setMonitoredVehicleJourney(new MonitoredVehicleJourney());
SiriSupportV2.fillMonitoredVehicleJourney(output.getMonitoredVehicleJourney(), tripDetailsForCurrentTrip.getTrip(), tripDetailsForCurrentTrip.getStatus(), null, OnwardCallsMode.VEHICLE_MONITORING, _presentationService, _transitDataService, maximumOnwardCalls, timePredictionRecords, tripDetailsForCurrentTrip.getStatus().isPredicted(), showApc, detailLevel, currentTime, null);
}
return output;
}
return null;
}
use of uk.org.siri.siri20.VehicleActivityStructure in project OpenTripPlanner by opentripplanner.
the class SiriTimetableSnapshotSource method applyVehicleMonitoring.
/**
* 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 applyVehicleMonitoring(final Graph graph, final String feedId, final boolean fullDataset, final List<VehicleMonitoringDeliveryStructure> 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 (VehicleMonitoringDeliveryStructure vmDelivery : updates) {
ServiceDate serviceDate = new ServiceDate();
List<VehicleActivityStructure> activities = vmDelivery.getVehicleActivities();
if (activities != null) {
// Handle activities
LOG.info("Handling {} VM-activities.", activities.size());
int handledCounter = 0;
int skippedCounter = 0;
for (VehicleActivityStructure activity : activities) {
boolean handled = handleModifiedTrip(graph, feedId, activity, serviceDate);
if (handled) {
handledCounter++;
} else {
skippedCounter++;
}
}
LOG.info("Applied {} VM-activities, skipped {}.", handledCounter, skippedCounter);
}
List<VehicleActivityCancellationStructure> cancellations = vmDelivery.getVehicleActivityCancellations();
if (cancellations != null && !cancellations.isEmpty()) {
// Handle cancellations
LOG.info("TODO: Handle {} cancellations.", cancellations.size());
}
List<NaturalLanguageStringStructure> notes = vmDelivery.getVehicleActivityNotes();
if (notes != null && !notes.isEmpty()) {
// Handle notes
LOG.info("TODO: Handle {} notes.", notes.size());
}
}
// 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();
if (keepLogging) {
LOG.info("Reducing SIRI-VM logging until restart");
keepLogging = false;
}
}
}
Aggregations