use of org.opentripplanner.model.Stop in project OpenTripPlanner by opentripplanner.
the class NearbyStopFinder method findNearbyStopsConsideringPatterns.
/**
* Find all unique nearby stops that are the closest stop on some trip pattern or flex trip.
* Note that the result will include the origin vertex if it is an instance of StopVertex.
* This is intentional: we don't want to return the next stop down the line for trip patterns that pass through the
* origin vertex.
*/
public Set<StopAtDistance> findNearbyStopsConsideringPatterns(Vertex vertex, boolean reverseDirection) {
/* Track the closest stop on each pattern passing nearby. */
MinMap<TripPattern, StopAtDistance> closestStopForPattern = new MinMap<TripPattern, StopAtDistance>();
/* Track the closest stop on each flex trip nearby. */
MinMap<FlexTrip, StopAtDistance> closestStopForFlexTrip = new MinMap<>();
/* Iterate over nearby stops via the street network or using straight-line distance, depending on the graph. */
for (StopAtDistance stopAtDistance : findNearbyStops(vertex, reverseDirection)) {
StopLocation ts1 = stopAtDistance.stop;
if (ts1 instanceof Stop) {
/* Consider this destination stop as a candidate for every trip pattern passing through it. */
for (TripPattern pattern : graph.index.getPatternsForStop(ts1)) {
closestStopForPattern.putMin(pattern, stopAtDistance);
}
}
if (OTPFeature.FlexRouting.isOn()) {
for (FlexTrip trip : graph.index.getFlexIndex().flexTripsByStop.get(ts1)) {
closestStopForFlexTrip.putMin(trip, stopAtDistance);
}
}
}
/* Make a transfer from the origin stop to each destination stop that was the closest stop on any pattern. */
Set<StopAtDistance> uniqueStops = Sets.newHashSet();
uniqueStops.addAll(closestStopForFlexTrip.values());
uniqueStops.addAll(closestStopForPattern.values());
return uniqueStops;
}
use of org.opentripplanner.model.Stop in project OpenTripPlanner by opentripplanner.
the class SiriTimetableSnapshotSource method getTripForJourney.
/**
* Finds the correct trip based on OTP-ServiceDate and SIRI-DepartureTime
* @param trips
* @param journey
* @return
*/
private Set<Trip> getTripForJourney(Set<Trip> trips, EstimatedVehicleJourney journey) {
List<RecordedCall> recordedCalls = (journey.getRecordedCalls() != null ? journey.getRecordedCalls().getRecordedCalls() : new ArrayList<>());
List<EstimatedCall> estimatedCalls = journey.getEstimatedCalls().getEstimatedCalls();
ZonedDateTime date;
int stopNumber = 1;
String firstStopId;
if (recordedCalls != null && !recordedCalls.isEmpty()) {
RecordedCall recordedCall = recordedCalls.get(0);
date = recordedCall.getAimedDepartureTime();
firstStopId = recordedCall.getStopPointRef().getValue();
} else if (estimatedCalls != null && !estimatedCalls.isEmpty()) {
EstimatedCall estimatedCall = estimatedCalls.get(0);
if (estimatedCall.getOrder() != null) {
stopNumber = estimatedCall.getOrder().intValue();
} else if (estimatedCall.getVisitNumber() != null) {
stopNumber = estimatedCall.getVisitNumber().intValue();
}
firstStopId = estimatedCall.getStopPointRef().getValue();
date = estimatedCall.getAimedDepartureTime();
} else {
return null;
}
if (date == null) {
// If no date is set - assume Realtime-data is reported for 'today'.
date = ZonedDateTime.now();
}
ServiceDate serviceDate = new ServiceDate(date.getYear(), date.getMonthValue(), date.getDayOfMonth());
int departureInSecondsSinceMidnight = calculateSecondsSinceMidnight(date);
Set<Trip> result = new HashSet<>();
for (Iterator<Trip> iterator = trips.iterator(); iterator.hasNext(); ) {
Trip trip = iterator.next();
Set<ServiceDate> serviceDatesForServiceId = routingService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId());
if (serviceDatesForServiceId.contains(serviceDate)) {
TripPattern pattern = routingService.getPatternForTrip().get(trip);
if (stopNumber < pattern.stopPattern.stops.length) {
boolean firstReportedStopIsFound = false;
Stop stop = pattern.stopPattern.stops[stopNumber - 1];
if (firstStopId.equals(stop.getId().getId())) {
firstReportedStopIsFound = true;
} else {
String agencyId = stop.getId().getFeedId();
if (stop.isPartOfStation()) {
Stop alternativeStop = routingService.getStopForId(new FeedScopedId(agencyId, firstStopId));
if (stop.isPartOfSameStationAs(alternativeStop)) {
firstReportedStopIsFound = true;
}
}
}
if (firstReportedStopIsFound) {
for (TripTimes times : getCurrentTimetable(pattern, serviceDate).tripTimes) {
if (times.getScheduledDepartureTime(stopNumber - 1) == departureInSecondsSinceMidnight) {
if (routingService.getCalendarService().getServiceDatesForServiceId(times.trip.getServiceId()).contains(serviceDate)) {
result.add(times.trip);
}
}
}
}
}
}
}
if (result.size() >= 1) {
return result;
} else {
return null;
}
}
use of org.opentripplanner.model.Stop in project OpenTripPlanner by opentripplanner.
the class SiriTimetableSnapshotSource method handleAddedTrip.
private boolean handleAddedTrip(Graph graph, String feedId, EstimatedVehicleJourney estimatedVehicleJourney) {
// Verifying values required in SIRI Profile
// Added ServiceJourneyId
String newServiceJourneyRef = estimatedVehicleJourney.getEstimatedVehicleJourneyCode();
Preconditions.checkNotNull(newServiceJourneyRef, "EstimatedVehicleJourneyCode is required");
// Replaced/duplicated ServiceJourneyId
// VehicleJourneyRef existingServiceJourneyRef = estimatedVehicleJourney.getVehicleJourneyRef();
// Preconditions.checkNotNull(existingServiceJourneyRef, "VehicleJourneyRef is required");
// LineRef of added trip
Preconditions.checkNotNull(estimatedVehicleJourney.getLineRef(), "LineRef is required");
String lineRef = estimatedVehicleJourney.getLineRef().getValue();
// OperatorRef of added trip
Preconditions.checkNotNull(estimatedVehicleJourney.getOperatorRef(), "OperatorRef is required");
String operatorRef = estimatedVehicleJourney.getOperatorRef().getValue();
// Required in SIRI, but currently not in use by OTP
// Preconditions.checkNotNull(estimatedVehicleJourney.getRouteRef(), "RouteRef is required");
// String routeRef = estimatedVehicleJourney.getRouteRef().getValue();
// Preconditions.checkNotNull(estimatedVehicleJourney.getGroupOfLinesRef(), "GroupOfLinesRef is required");
// String groupOfLines = estimatedVehicleJourney.getGroupOfLinesRef().getValue();
// Preconditions.checkNotNull(estimatedVehicleJourney.getExternalLineRef(), "ExternalLineRef is required");
String externalLineRef = estimatedVehicleJourney.getExternalLineRef().getValue();
// TODO - SIRI: Where is the Operator?
// Operator operator = graphIndex.operatorForId.get(new FeedScopedId(feedId, operatorRef));
// Preconditions.checkNotNull(operator, "Operator " + operatorRef + " is unknown");
FeedScopedId tripId = new FeedScopedId(feedId, newServiceJourneyRef);
FeedScopedId serviceId = new FeedScopedId(feedId, newServiceJourneyRef);
Route replacedRoute = null;
if (externalLineRef != null) {
replacedRoute = graph.index.getRouteForId(new FeedScopedId(feedId, externalLineRef));
}
FeedScopedId routeId = new FeedScopedId(feedId, lineRef);
Route route = graph.index.getRouteForId(routeId);
if (route == null) {
// Route is unknown - create new
route = new Route();
route.setId(routeId);
route.setType(getRouteType(estimatedVehicleJourney.getVehicleModes()));
// route.setOperator(operator);
// TODO - SIRI: Is there a better way to find authority/Agency?
// Finding first Route with same Operator, and using same Authority
Agency agency = graph.index.getAllRoutes().stream().findFirst().get().getAgency();
route.setAgency(agency);
if (estimatedVehicleJourney.getPublishedLineNames() != null && !estimatedVehicleJourney.getPublishedLineNames().isEmpty()) {
route.setShortName("" + estimatedVehicleJourney.getPublishedLineNames().get(0).getValue());
}
LOG.info("Adding route {} to graph.", routeId);
graph.index.addRoutes(route);
}
Trip trip = new Trip();
trip.setId(tripId);
trip.setRoute(route);
// TODO - SIRI: Set transport-submode based on replaced- and replacement-route
if (replacedRoute != null) {
if (replacedRoute.getType() >= 100 && replacedRoute.getType() < 200) {
// Replaced-route is RAIL
if (route.getType() == 100) {
// Replacement-route is also RAIL
// trip.setTransportSubmode(TransmodelTransportSubmode.REPLACEMENT_RAIL_SERVICE);
} else if (route.getType() == 700) {
// Replacement-route is BUS
// trip.setTransportSubmode(TransmodelTransportSubmode.RAIL_REPLACEMENT_BUS);
}
}
}
trip.setServiceId(serviceId);
// TODO - SIRI: PublishedLineName not defined in SIRI-profile
if (estimatedVehicleJourney.getPublishedLineNames() != null && !estimatedVehicleJourney.getPublishedLineNames().isEmpty()) {
trip.setRouteShortName("" + estimatedVehicleJourney.getPublishedLineNames().get(0).getValue());
}
// trip.setTripOperator(operator);
// TODO - SIRI: Populate these?
// Replacement-trip has different shape
trip.setShapeId(null);
// trip.setTripPrivateCode(null);
// trip.setTripPublicCode(null);
trip.setBlockId(null);
trip.setTripShortName(null);
trip.setTripHeadsign(null);
// trip.setKeyValues(null);
List<Stop> addedStops = new ArrayList<>();
List<StopTime> aimedStopTimes = new ArrayList<>();
List<EstimatedCall> estimatedCalls = estimatedVehicleJourney.getEstimatedCalls().getEstimatedCalls();
for (int i = 0; i < estimatedCalls.size(); i++) {
EstimatedCall estimatedCall = estimatedCalls.get(i);
Stop stop = getStopForStopId(feedId, estimatedCall.getStopPointRef().getValue());
StopTime stopTime = new StopTime();
stopTime.setStop(stop);
stopTime.setStopSequence(i);
stopTime.setTrip(trip);
ZonedDateTime aimedArrivalTime = estimatedCall.getAimedArrivalTime();
ZonedDateTime aimedDepartureTime = estimatedCall.getAimedDepartureTime();
if (aimedArrivalTime != null) {
stopTime.setArrivalTime(calculateSecondsSinceMidnight(aimedArrivalTime));
}
if (aimedDepartureTime != null) {
stopTime.setDepartureTime(calculateSecondsSinceMidnight(aimedDepartureTime));
}
if (estimatedCall.getArrivalBoardingActivity() == ArrivalBoardingActivityEnumeration.ALIGHTING) {
stopTime.setDropOffType(PICKDROP_SCHEDULED);
} else {
stopTime.setDropOffType(PICKDROP_NONE);
}
if (estimatedCall.getDepartureBoardingActivity() == DepartureBoardingActivityEnumeration.BOARDING) {
stopTime.setPickupType(PICKDROP_SCHEDULED);
} else {
stopTime.setPickupType(PICKDROP_NONE);
}
if (estimatedCall.getDestinationDisplaies() != null && !estimatedCall.getDestinationDisplaies().isEmpty()) {
NaturalLanguageStringStructure destinationDisplay = estimatedCall.getDestinationDisplaies().get(0);
stopTime.setStopHeadsign(destinationDisplay.getValue());
}
if (i == 0) {
// Fake arrival on first stop
stopTime.setArrivalTime(stopTime.getDepartureTime());
} else if (i == (estimatedCalls.size() - 1)) {
// Fake departure from last stop
stopTime.setDepartureTime(stopTime.getArrivalTime());
}
addedStops.add(stop);
aimedStopTimes.add(stopTime);
}
StopPattern stopPattern = new StopPattern(aimedStopTimes);
TripPattern pattern = new TripPattern(trip.getRoute(), stopPattern);
TripTimes tripTimes = new TripTimes(trip, aimedStopTimes, graph.deduplicator);
boolean isJourneyPredictionInaccurate = (estimatedVehicleJourney.isPredictionInaccurate() != null && estimatedVehicleJourney.isPredictionInaccurate());
// If added trip is updated with realtime - loop through and add delays
for (int i = 0; i < estimatedCalls.size(); i++) {
EstimatedCall estimatedCall = estimatedCalls.get(i);
ZonedDateTime expectedArrival = estimatedCall.getExpectedArrivalTime();
ZonedDateTime expectedDeparture = estimatedCall.getExpectedDepartureTime();
int aimedArrivalTime = aimedStopTimes.get(i).getArrivalTime();
int aimedDepartureTime = aimedStopTimes.get(i).getDepartureTime();
if (expectedArrival != null) {
int expectedArrivalTime = calculateSecondsSinceMidnight(expectedArrival);
tripTimes.updateArrivalDelay(i, expectedArrivalTime - aimedArrivalTime);
}
if (expectedDeparture != null) {
int expectedDepartureTime = calculateSecondsSinceMidnight(expectedDeparture);
tripTimes.updateDepartureDelay(i, expectedDepartureTime - aimedDepartureTime);
}
if (estimatedCall.isCancellation() != null) {
tripTimes.setCancelledStop(i, estimatedCall.isCancellation());
}
boolean isCallPredictionInaccurate = estimatedCall.isPredictionInaccurate() != null && estimatedCall.isPredictionInaccurate();
tripTimes.setPredictionInaccurate(i, (isJourneyPredictionInaccurate | isCallPredictionInaccurate));
if (i == 0) {
// Fake arrival on first stop
tripTimes.updateArrivalTime(i, tripTimes.getDepartureTime(i));
} else if (i == (estimatedCalls.size() - 1)) {
// Fake departure from last stop
tripTimes.updateDepartureTime(i, tripTimes.getArrivalTime(i));
}
}
// Adding trip to index necessary to include values in graphql-queries
// TODO - SIRI: should more data be added to index?
graph.index.getTripForId().put(tripId, trip);
graph.index.getPatternForTrip().put(trip, pattern);
if (estimatedVehicleJourney.isCancellation() != null && estimatedVehicleJourney.isCancellation()) {
tripTimes.cancel();
} else {
tripTimes.setRealTimeState(RealTimeState.ADDED);
}
if (!graph.getServiceCodes().containsKey(serviceId)) {
graph.getServiceCodes().put(serviceId, graph.getServiceCodes().size());
}
tripTimes.serviceCode = graph.getServiceCodes().get(serviceId);
pattern.add(tripTimes);
Preconditions.checkState(tripTimes.timesIncreasing(), "Non-increasing triptimes for added trip");
ServiceDate serviceDate = getServiceDateForEstimatedVehicleJourney(estimatedVehicleJourney);
if (graph.getCalendarService().getServiceDatesForServiceId(serviceId) == null || graph.getCalendarService().getServiceDatesForServiceId(serviceId).isEmpty()) {
LOG.info("Adding serviceId {} to CalendarService", serviceId);
// TODO - SIRI: Need to add the ExtraJourney as a Trip - alerts may be attached to it
// graph.getCalendarService().addServiceIdAndServiceDates(serviceId, Arrays.asList(serviceDate));
}
return addTripToGraphAndBuffer(feedId, graph, trip, aimedStopTimes, addedStops, tripTimes, serviceDate);
}
use of org.opentripplanner.model.Stop 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 oldTimes
* @param journey SIRI-ET EstimatedVehicleJourney
* @param trip
* @param routingService
* @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;
}
EstimatedVehicleJourney.EstimatedCalls journeyCalls = journey.getEstimatedCalls();
if (journeyCalls == null) {
return null;
}
List<EstimatedCall> estimatedCalls = journeyCalls.getEstimatedCalls();
List<Stop> 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++) {
Stop stop = stops.get(i);
final StopTime stopTime = new StopTime();
stopTime.setStop(stop);
stopTime.setTrip(trip);
stopTime.setStopSequence(i);
stopTime.setDropOffType(timetable.pattern.stopPattern.dropoffs[i]);
stopTime.setPickupType(timetable.pattern.stopPattern.pickups[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 (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()) {
Stop 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.setDropOffType(PICKDROP_NONE);
} else if (estimatedCall.getArrivalBoardingActivity() == ArrivalBoardingActivityEnumeration.ALIGHTING) {
stopTime.setDropOffType(PICKDROP_SCHEDULED);
} else if (estimatedCall.getArrivalBoardingActivity() == ArrivalBoardingActivityEnumeration.NO_ALIGHTING) {
stopTime.setDropOffType(PICKDROP_NONE);
} else if (estimatedCall.getArrivalBoardingActivity() == null && i == 0) {
// First stop - default no pickup
stopTime.setDropOffType(PICKDROP_NONE);
}
CallStatusEnumeration departureStatus = estimatedCall.getDepartureStatus();
if (departureStatus == CallStatusEnumeration.CANCELLED) {
stopTime.setPickupType(PICKDROP_NONE);
} else if (estimatedCall.getDepartureBoardingActivity() == DepartureBoardingActivityEnumeration.BOARDING) {
stopTime.setPickupType(PICKDROP_SCHEDULED);
} else if (estimatedCall.getDepartureBoardingActivity() == DepartureBoardingActivityEnumeration.NO_BOARDING) {
stopTime.setPickupType(PICKDROP_NONE);
} else if (estimatedCall.getDepartureBoardingActivity() == null && i == (stops.size() - 1)) {
// Last stop - default no dropoff
stopTime.setPickupType(PICKDROP_NONE);
}
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 org.opentripplanner.model.Stop in project OpenTripPlanner by opentripplanner.
the class TimetableHelper method createModifiedStops.
/**
* Apply the SIRI ET to the appropriate TripTimes from this Timetable.
* Calculate new stoppattern based on single stop cancellations
*
* @param journey SIRI-ET EstimatedVehicleJourney
* @param routingService
* @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<Stop> createModifiedStops(Timetable timetable, EstimatedVehicleJourney journey, RoutingService routingService) {
if (journey == null) {
return null;
}
EstimatedVehicleJourney.EstimatedCalls journeyEstimatedCalls = journey.getEstimatedCalls();
EstimatedVehicleJourney.RecordedCalls journeyRecordedCalls = journey.getRecordedCalls();
if (journeyEstimatedCalls == null) {
return null;
}
List<EstimatedCall> estimatedCalls = journeyEstimatedCalls.getEstimatedCalls();
List<RecordedCall> recordedCalls;
if (journeyRecordedCalls != null) {
recordedCalls = journeyRecordedCalls.getRecordedCalls();
} else {
recordedCalls = new ArrayList<>();
}
// Get all scheduled stops
Stop[] stops = timetable.pattern.stopPattern.stops;
List<Stop> modifiedStops = new ArrayList<>();
for (int i = 0; i < stops.length; i++) {
Stop stop = stops[i];
boolean foundMatch = false;
if (i < recordedCalls.size()) {
for (RecordedCall recordedCall : recordedCalls) {
// Current stop is being updated
boolean stopsMatchById = stop.getId().getId().equals(recordedCall.getStopPointRef().getValue());
if (!stopsMatchById && stop.isPartOfStation()) {
Stop alternativeStop = routingService.getStopForId(new FeedScopedId(stop.getId().getFeedId(), recordedCall.getStopPointRef().getValue()));
if (alternativeStop != null && stop.isPartOfSameStationAs(alternativeStop)) {
stopsMatchById = true;
stop = alternativeStop;
}
}
if (stopsMatchById) {
foundMatch = true;
modifiedStops.add(stop);
break;
}
}
} else {
for (EstimatedCall estimatedCall : estimatedCalls) {
// Current stop is being updated
boolean stopsMatchById = stop.getId().getId().equals(estimatedCall.getStopPointRef().getValue());
if (!stopsMatchById && stop.isPartOfStation()) {
Stop alternativeStop = routingService.getStopForId(new FeedScopedId(stop.getId().getFeedId(), estimatedCall.getStopPointRef().getValue()));
if (alternativeStop != null && stop.isPartOfSameStationAs(alternativeStop)) {
stopsMatchById = true;
stop = alternativeStop;
}
}
if (stopsMatchById) {
foundMatch = true;
modifiedStops.add(stop);
break;
}
}
}
if (!foundMatch) {
modifiedStops.add(stop);
}
}
return modifiedStops;
}
Aggregations