use of com.conveyal.gtfs.model.StopTime in project graphhopper by graphhopper.
the class GtfsReader method addDelayedBoardEdge.
int addDelayedBoardEdge(ZoneId zoneId, GtfsRealtime.TripDescriptor tripDescriptor, int stopSequence, int departureTime, int departureNode, BitSet validOnDay) {
Trip trip = feed.trips.get(tripDescriptor.getTripId());
final int departureTimelineNode = i++;
StopTime stopTime = feed.stop_times.get(new Fun.Tuple2(tripDescriptor.getTripId(), stopSequence));
Stop stop = feed.stops.get(stopTime.stop_id);
nodeAccess.setNode(departureTimelineNode, stop.stop_lat, stop.stop_lon);
nodeAccess.setAdditionalNodeField(departureTimelineNode, NodeType.INTERNAL_PT.ordinal());
times.put(departureTimelineNode, departureTime);
departureTimelineNodes.put(stopTime.stop_id, new TimelineNodeIdWithTripId(departureTimelineNode, tripDescriptor.getTripId(), trip.route_id));
int dayShift = departureTime / (24 * 60 * 60);
GtfsStorage.Validity validOn = new GtfsStorage.Validity(getValidOn(validOnDay, dayShift), zoneId, startDate);
int validityId;
if (gtfsStorage.getOperatingDayPatterns().containsKey(validOn)) {
validityId = gtfsStorage.getOperatingDayPatterns().get(validOn);
} else {
validityId = gtfsStorage.getOperatingDayPatterns().size();
gtfsStorage.getOperatingDayPatterns().put(validOn, validityId);
}
EdgeIteratorState boardEdge = graph.edge(departureTimelineNode, departureNode, 0.0, false);
boardEdge.setName(getRouteName(feed, trip));
setEdgeType(boardEdge, GtfsStorage.EdgeType.BOARD);
gtfsStorage.getStopSequences().put(boardEdge.getEdge(), stopSequence);
gtfsStorage.getTripDescriptors().put(boardEdge.getEdge(), tripDescriptor.toByteArray());
boardEdge.setFlags(encoder.setValidityId(boardEdge.getFlags(), validityId));
boardEdge.setFlags(encoder.setTransfers(boardEdge.getFlags(), 1));
return boardEdge.getEdge();
}
use of com.conveyal.gtfs.model.StopTime in project graphhopper by graphhopper.
the class GtfsReader method buildPtNetwork.
private void buildPtNetwork() {
HashMultimap<String, Trip> blockTrips = HashMultimap.create();
for (Trip trip : feed.trips.values()) {
if (trip.block_id != null) {
blockTrips.put(trip.block_id, trip);
} else {
blockTrips.put("non-block-trip" + trip.trip_id, trip);
}
}
blockTrips.asMap().values().forEach(unsortedTrips -> {
List<TripWithStopTimes> trips = unsortedTrips.stream().map(trip -> {
Service service = feed.services.get(trip.service_id);
BitSet validOnDay = new BitSet((int) DAYS.between(startDate, endDate));
for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
if (service.activeOn(date)) {
validOnDay.set((int) DAYS.between(startDate, date));
}
}
ArrayList<StopTime> stopTimes = new ArrayList<>();
getInterpolatedStopTimesForTrip(trip.trip_id).forEach(stopTimes::add);
return new TripWithStopTimes(trip, stopTimes, validOnDay, Collections.emptySet(), Collections.emptySet());
}).sorted(Comparator.comparingInt(trip -> trip.stopTimes.iterator().next().departure_time)).collect(Collectors.toList());
if (trips.stream().map(trip -> feed.getFrequencies(trip.trip.trip_id)).distinct().count() != 1) {
throw new RuntimeException("Found a block with frequency-based trips. Not supported.");
}
ZoneId zoneId = ZoneId.of(feed.agency.get(feed.routes.get(trips.iterator().next().trip.route_id).agency_id).agency_timezone);
Collection<Frequency> frequencies = feed.getFrequencies(trips.iterator().next().trip.trip_id);
if (frequencies.isEmpty()) {
addTrips(zoneId, trips, 0, false);
} else {
for (Frequency frequency : frequencies) {
for (int time = frequency.start_time; time < frequency.end_time; time += frequency.headway_secs) {
addTrips(zoneId, trips, time, true);
}
}
}
});
wireUpStops();
}
use of com.conveyal.gtfs.model.StopTime in project graphhopper by graphhopper.
the class RealtimeFeed method fromProtobuf.
public static RealtimeFeed fromProtobuf(GraphHopperStorage graphHopperStorage, GtfsStorage staticGtfs, Map<String, Transfers> transfers, Map<String, GtfsRealtime.FeedMessage> feedMessages) {
final IntHashSet blockedEdges = new IntHashSet();
final IntLongHashMap delaysForBoardEdges = new IntLongHashMap();
final IntLongHashMap delaysForAlightEdges = new IntLongHashMap();
final LinkedList<PtGraph.PtEdge> additionalEdges = new LinkedList<>();
final GtfsReader.PtGraphOut overlayGraph = new GtfsReader.PtGraphOut() {
int nextEdge = staticGtfs.getPtGraph().getEdgeCount();
int nextNode = staticGtfs.getPtGraph().getNodeCount();
@Override
public int createEdge(int src, int dest, PtEdgeAttributes attrs) {
int edgeId = nextEdge++;
additionalEdges.add(new PtGraph.PtEdge(edgeId, src, dest, attrs));
return edgeId;
}
@Override
public int createNode() {
return nextNode++;
}
};
feedMessages.forEach((feedKey, feedMessage) -> {
GTFSFeed feed = staticGtfs.getGtfsFeeds().get(feedKey);
ZoneId timezone = ZoneId.of(feed.agency.values().stream().findFirst().get().agency_timezone);
PtGraph ptGraphNodesAndEdges = staticGtfs.getPtGraph();
final GtfsReader gtfsReader = new GtfsReader(feedKey, graphHopperStorage, ptGraphNodesAndEdges, overlayGraph, staticGtfs, null, transfers.get(feedKey), null);
Instant timestamp = Instant.ofEpochSecond(feedMessage.getHeader().getTimestamp());
// FIXME
LocalDate dateToChange = timestamp.atZone(timezone).toLocalDate();
BitSet validOnDay = new BitSet();
LocalDate startDate = feed.getStartDate();
validOnDay.set((int) DAYS.between(startDate, dateToChange));
feedMessage.getEntityList().stream().filter(GtfsRealtime.FeedEntity::hasTripUpdate).map(GtfsRealtime.FeedEntity::getTripUpdate).filter(tripUpdate -> tripUpdate.getTrip().getScheduleRelationship() == GtfsRealtime.TripDescriptor.ScheduleRelationship.SCHEDULED).forEach(tripUpdate -> {
Collection<Frequency> frequencies = feed.getFrequencies(tripUpdate.getTrip().getTripId());
int timeOffset = (tripUpdate.getTrip().hasStartTime() && !frequencies.isEmpty()) ? LocalTime.parse(tripUpdate.getTrip().getStartTime()).toSecondOfDay() : 0;
final int[] boardEdges = findBoardEdgesForTrip(staticGtfs, feedKey, feed, tripUpdate);
final int[] leaveEdges = findLeaveEdgesForTrip(staticGtfs, feedKey, feed, tripUpdate);
if (boardEdges == null || leaveEdges == null) {
logger.warn("Trip not found: {}", tripUpdate.getTrip());
return;
}
tripUpdate.getStopTimeUpdateList().stream().filter(stopTimeUpdate -> stopTimeUpdate.getScheduleRelationship() == SKIPPED).mapToInt(GtfsRealtime.TripUpdate.StopTimeUpdate::getStopSequence).forEach(skippedStopSequenceNumber -> {
blockedEdges.add(boardEdges[skippedStopSequenceNumber]);
blockedEdges.add(leaveEdges[skippedStopSequenceNumber]);
});
GtfsReader.TripWithStopTimes tripWithStopTimes = toTripWithStopTimes(feed, tripUpdate);
tripWithStopTimes.stopTimes.forEach(stopTime -> {
if (stopTime.stop_sequence > leaveEdges.length - 1) {
logger.warn("Stop sequence number too high {} vs {}", stopTime.stop_sequence, leaveEdges.length);
return;
}
final StopTime originalStopTime = feed.stop_times.get(new Fun.Tuple2(tripUpdate.getTrip().getTripId(), stopTime.stop_sequence));
int arrivalDelay = stopTime.arrival_time - originalStopTime.arrival_time;
delaysForAlightEdges.put(leaveEdges[stopTime.stop_sequence], arrivalDelay * 1000);
int departureDelay = stopTime.departure_time - originalStopTime.departure_time;
if (departureDelay > 0) {
int boardEdge = boardEdges[stopTime.stop_sequence];
int departureNode = ptGraphNodesAndEdges.edge(boardEdge).getAdjNode();
int delayedBoardEdge = gtfsReader.addDelayedBoardEdge(timezone, tripUpdate.getTrip(), stopTime.stop_sequence, stopTime.departure_time + timeOffset, departureNode, validOnDay);
delaysForBoardEdges.put(delayedBoardEdge, departureDelay * 1000);
}
});
});
feedMessage.getEntityList().stream().filter(GtfsRealtime.FeedEntity::hasTripUpdate).map(GtfsRealtime.FeedEntity::getTripUpdate).filter(tripUpdate -> tripUpdate.getTrip().getScheduleRelationship() == GtfsRealtime.TripDescriptor.ScheduleRelationship.ADDED).forEach(tripUpdate -> {
Trip trip = new Trip();
trip.trip_id = tripUpdate.getTrip().getTripId();
trip.route_id = tripUpdate.getTrip().getRouteId();
final List<StopTime> stopTimes = tripUpdate.getStopTimeUpdateList().stream().map(stopTimeUpdate -> {
final StopTime stopTime = new StopTime();
stopTime.stop_sequence = stopTimeUpdate.getStopSequence();
stopTime.stop_id = stopTimeUpdate.getStopId();
stopTime.trip_id = trip.trip_id;
final ZonedDateTime arrival_time = Instant.ofEpochSecond(stopTimeUpdate.getArrival().getTime()).atZone(timezone);
stopTime.arrival_time = (int) Duration.between(arrival_time.truncatedTo(ChronoUnit.DAYS), arrival_time).getSeconds();
final ZonedDateTime departure_time = Instant.ofEpochSecond(stopTimeUpdate.getArrival().getTime()).atZone(timezone);
stopTime.departure_time = (int) Duration.between(departure_time.truncatedTo(ChronoUnit.DAYS), departure_time).getSeconds();
return stopTime;
}).collect(Collectors.toList());
GtfsReader.TripWithStopTimes tripWithStopTimes = new GtfsReader.TripWithStopTimes(trip, stopTimes, validOnDay, Collections.emptySet(), Collections.emptySet());
gtfsReader.addTrip(timezone, 0, new ArrayList<>(), tripWithStopTimes, tripUpdate.getTrip());
});
gtfsReader.wireUpAdditionalDeparturesAndArrivals(timezone);
});
return new RealtimeFeed(feedMessages, blockedEdges, delaysForBoardEdges, delaysForAlightEdges, additionalEdges);
}
use of com.conveyal.gtfs.model.StopTime in project graphhopper by graphhopper.
the class RealtimeFeed method findBoardEdgesForTrip.
private static int[] findBoardEdgesForTrip(GtfsStorage staticGtfs, String feedKey, GTFSFeed feed, GtfsRealtime.TripUpdate tripUpdate) {
Trip trip = feed.trips.get(tripUpdate.getTrip().getTripId());
StopTime next = feed.getOrderedStopTimesForTrip(trip.trip_id).iterator().next();
int station = staticGtfs.getStationNodes().get(new GtfsStorage.FeedIdWithStopId(feedKey, next.stop_id));
Optional<PtGraph.PtEdge> firstBoarding = StreamSupport.stream(staticGtfs.getPtGraph().edgesAround(station).spliterator(), false).flatMap(e -> StreamSupport.stream(staticGtfs.getPtGraph().edgesAround(e.getAdjNode()).spliterator(), false)).flatMap(e -> StreamSupport.stream(staticGtfs.getPtGraph().edgesAround(e.getAdjNode()).spliterator(), false)).filter(e -> e.getType() == GtfsStorage.EdgeType.BOARD).filter(e -> normalize(e.getAttrs().tripDescriptor).equals(tripUpdate.getTrip())).findAny();
int n = firstBoarding.get().getAdjNode();
Stream<PtGraph.PtEdge> boardEdges = evenIndexed(nodes(hopDwellChain(staticGtfs, n))).mapToObj(e -> boardForAdjNode(staticGtfs, e));
return collectWithPadding(boardEdges);
}
Aggregations