Search in sources :

Example 1 with StopTime

use of com.conveyal.gtfs.model.StopTime in project graphhopper by graphhopper.

the class GtfsReader method addTrip.

void addTrip(ZoneId zoneId, int time, List<TripWithStopTimeAndArrivalNode> arrivalNodes, GtfsReader.TripWithStopTimes trip, GtfsRealtime.TripDescriptor tripDescriptor) {
    IntArrayList boardEdges = new IntArrayList();
    IntArrayList alightEdges = new IntArrayList();
    StopTime prev = null;
    int arrivalNode = -1;
    int departureNode = -1;
    for (StopTime stopTime : trip.stopTimes) {
        Stop stop = feed.stops.get(stopTime.stop_id);
        arrivalNode = i++;
        nodeAccess.setNode(arrivalNode, stop.stop_lat, stop.stop_lon);
        nodeAccess.setAdditionalNodeField(arrivalNode, NodeType.INTERNAL_PT.ordinal());
        times.put(arrivalNode, stopTime.arrival_time + time);
        if (prev != null) {
            Stop fromStop = feed.stops.get(prev.stop_id);
            double distance = distCalc.calcDist(fromStop.stop_lat, fromStop.stop_lon, stop.stop_lat, stop.stop_lon);
            EdgeIteratorState edge = graph.edge(departureNode, arrivalNode, distance, false);
            edge.setName(stop.stop_name);
            setEdgeType(edge, GtfsStorage.EdgeType.HOP);
            edge.setFlags(encoder.setTime(edge.getFlags(), stopTime.arrival_time - prev.departure_time));
            gtfsStorage.getStopSequences().put(edge.getEdge(), stopTime.stop_sequence);
        }
        final int departureTimelineNode = i++;
        nodeAccess.setNode(departureTimelineNode, stop.stop_lat, stop.stop_lon);
        nodeAccess.setAdditionalNodeField(departureTimelineNode, NodeType.INTERNAL_PT.ordinal());
        times.put(departureTimelineNode, stopTime.departure_time + time);
        departureTimelineNodes.put(stopTime.stop_id, new TimelineNodeIdWithTripId(departureTimelineNode, trip.trip.trip_id, trip.trip.route_id));
        final int arrivalTimelineNode = i++;
        nodeAccess.setNode(arrivalTimelineNode, stop.stop_lat, stop.stop_lon);
        nodeAccess.setAdditionalNodeField(arrivalTimelineNode, NodeType.INTERNAL_PT.ordinal());
        times.put(arrivalTimelineNode, stopTime.arrival_time + time);
        arrivalTimelineNodes.put(stopTime.stop_id, new TimelineNodeIdWithTripId(arrivalTimelineNode, trip.trip.trip_id, trip.trip.route_id));
        departureNode = i++;
        nodeAccess.setNode(departureNode, stop.stop_lat, stop.stop_lon);
        nodeAccess.setAdditionalNodeField(departureNode, NodeType.INTERNAL_PT.ordinal());
        times.put(departureNode, stopTime.departure_time + time);
        int dayShift = stopTime.departure_time / (24 * 60 * 60);
        GtfsStorage.Validity validOn = new GtfsStorage.Validity(getValidOn(trip.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.trip));
        setEdgeType(boardEdge, GtfsStorage.EdgeType.BOARD);
        while (boardEdges.size() < stopTime.stop_sequence) {
            // Padding, so that index == stop_sequence
            boardEdges.add(-1);
        }
        boardEdges.add(boardEdge.getEdge());
        gtfsStorage.getStopSequences().put(boardEdge.getEdge(), stopTime.stop_sequence);
        gtfsStorage.getTripDescriptors().put(boardEdge.getEdge(), tripDescriptor.toByteArray());
        boardEdge.setFlags(encoder.setValidityId(boardEdge.getFlags(), validityId));
        boardEdge.setFlags(encoder.setTransfers(boardEdge.getFlags(), 1));
        EdgeIteratorState alightEdge = graph.edge(arrivalNode, arrivalTimelineNode, 0.0, false);
        alightEdge.setName(getRouteName(feed, trip.trip));
        setEdgeType(alightEdge, GtfsStorage.EdgeType.ALIGHT);
        while (alightEdges.size() < stopTime.stop_sequence) {
            alightEdges.add(-1);
        }
        alightEdges.add(alightEdge.getEdge());
        gtfsStorage.getStopSequences().put(alightEdge.getEdge(), stopTime.stop_sequence);
        gtfsStorage.getTripDescriptors().put(alightEdge.getEdge(), tripDescriptor.toByteArray());
        alightEdge.setFlags(encoder.setValidityId(alightEdge.getFlags(), validityId));
        // alightEdge.setFlags(encoder.setTransfers(alightEdge.getFlags(), 1));
        EdgeIteratorState dwellEdge = graph.edge(arrivalNode, departureNode, 0.0, false);
        dwellEdge.setName(getRouteName(feed, trip.trip));
        setEdgeType(dwellEdge, GtfsStorage.EdgeType.DWELL);
        dwellEdge.setFlags(encoder.setTime(dwellEdge.getFlags(), stopTime.departure_time - stopTime.arrival_time));
        if (prev == null) {
            insertInboundBlockTransfers(arrivalNodes, tripDescriptor, departureNode, stopTime, stop, validOn, zoneId);
        }
        prev = stopTime;
    }
    gtfsStorage.getBoardEdgesForTrip().put(GtfsStorage.tripKey(tripDescriptor.getTripId(), tripDescriptor.getStartTime()), boardEdges.toArray());
    gtfsStorage.getAlightEdgesForTrip().put(GtfsStorage.tripKey(tripDescriptor.getTripId(), tripDescriptor.getStartTime()), alightEdges.toArray());
    TripWithStopTimeAndArrivalNode tripWithStopTimeAndArrivalNode = new TripWithStopTimeAndArrivalNode();
    tripWithStopTimeAndArrivalNode.tripWithStopTimes = trip;
    tripWithStopTimeAndArrivalNode.arrivalNode = arrivalNode;
    arrivalNodes.add(tripWithStopTimeAndArrivalNode);
}
Also used : Stop(com.conveyal.gtfs.model.Stop) EdgeIteratorState(com.graphhopper.util.EdgeIteratorState) IntArrayList(com.carrotsearch.hppc.IntArrayList) StopTime(com.conveyal.gtfs.model.StopTime)

Example 2 with StopTime

use of com.conveyal.gtfs.model.StopTime in project graphhopper by graphhopper.

the class RealtimeFeed method toTripWithStopTimes.

public static GtfsReader.TripWithStopTimes toTripWithStopTimes(GTFSFeed feed, Agency agency, GtfsRealtime.TripUpdate tripUpdate) {
    logger.trace("{}", tripUpdate.getTrip());
    final List<StopTime> stopTimes = new ArrayList<>();
    Set<Integer> cancelledArrivals = new HashSet<>();
    Set<Integer> cancelledDepartures = new HashSet<>();
    Trip originalTrip = feed.trips.get(tripUpdate.getTrip().getTripId());
    Trip trip = new Trip();
    if (originalTrip != null) {
        trip.trip_id = originalTrip.trip_id;
        trip.route_id = originalTrip.route_id;
    } else {
        trip.trip_id = tripUpdate.getTrip().getTripId();
        trip.route_id = tripUpdate.getTrip().getRouteId();
    }
    int delay = 0;
    int time = -1;
    List<GtfsRealtime.TripUpdate.StopTimeUpdate> stopTimeUpdateListWithSentinel = new ArrayList<>(tripUpdate.getStopTimeUpdateList());
    Iterable<StopTime> interpolatedStopTimesForTrip;
    try {
        interpolatedStopTimesForTrip = feed.getInterpolatedStopTimesForTrip(tripUpdate.getTrip().getTripId());
    } catch (GTFSFeed.FirstAndLastStopsDoNotHaveTimes firstAndLastStopsDoNotHaveTimes) {
        throw new RuntimeException(firstAndLastStopsDoNotHaveTimes);
    }
    int stopSequenceCeiling = Math.max(stopTimeUpdateListWithSentinel.isEmpty() ? 0 : stopTimeUpdateListWithSentinel.get(stopTimeUpdateListWithSentinel.size() - 1).getStopSequence(), StreamSupport.stream(interpolatedStopTimesForTrip.spliterator(), false).mapToInt(stopTime -> stopTime.stop_sequence).max().orElse(0)) + 1;
    stopTimeUpdateListWithSentinel.add(GtfsRealtime.TripUpdate.StopTimeUpdate.newBuilder().setStopSequence(stopSequenceCeiling).setScheduleRelationship(NO_DATA).build());
    for (GtfsRealtime.TripUpdate.StopTimeUpdate stopTimeUpdate : stopTimeUpdateListWithSentinel) {
        int nextStopSequence = stopTimes.isEmpty() ? 1 : stopTimes.get(stopTimes.size() - 1).stop_sequence + 1;
        for (int i = nextStopSequence; i < stopTimeUpdate.getStopSequence(); i++) {
            StopTime previousOriginalStopTime = feed.stop_times.get(new Fun.Tuple2(tripUpdate.getTrip().getTripId(), i));
            if (previousOriginalStopTime == null) {
                // This can and does happen. Stop sequence numbers can be left out.
                continue;
            }
            StopTime updatedPreviousStopTime = previousOriginalStopTime.clone();
            updatedPreviousStopTime.arrival_time = Math.max(previousOriginalStopTime.arrival_time + delay, time);
            logger.trace("stop_sequence {} scheduled arrival {} updated arrival {}", i, previousOriginalStopTime.arrival_time, updatedPreviousStopTime.arrival_time);
            time = updatedPreviousStopTime.arrival_time;
            updatedPreviousStopTime.departure_time = Math.max(previousOriginalStopTime.departure_time + delay, time);
            logger.trace("stop_sequence {} scheduled departure {} updated departure {}", i, previousOriginalStopTime.departure_time, updatedPreviousStopTime.departure_time);
            time = updatedPreviousStopTime.departure_time;
            stopTimes.add(updatedPreviousStopTime);
            logger.trace("Number of stop times: {}", stopTimes.size());
        }
        final StopTime originalStopTime = feed.stop_times.get(new Fun.Tuple2(tripUpdate.getTrip().getTripId(), stopTimeUpdate.getStopSequence()));
        if (originalStopTime != null) {
            StopTime updatedStopTime = originalStopTime.clone();
            if (stopTimeUpdate.getScheduleRelationship() == NO_DATA) {
                delay = 0;
            }
            if (stopTimeUpdate.hasArrival()) {
                delay = stopTimeUpdate.getArrival().getDelay();
            }
            updatedStopTime.arrival_time = Math.max(originalStopTime.arrival_time + delay, time);
            logger.trace("stop_sequence {} scheduled arrival {} updated arrival {}", stopTimeUpdate.getStopSequence(), originalStopTime.arrival_time, updatedStopTime.arrival_time);
            time = updatedStopTime.arrival_time;
            if (stopTimeUpdate.hasDeparture()) {
                delay = stopTimeUpdate.getDeparture().getDelay();
            }
            updatedStopTime.departure_time = Math.max(originalStopTime.departure_time + delay, time);
            logger.trace("stop_sequence {} scheduled departure {} updated departure {}", stopTimeUpdate.getStopSequence(), originalStopTime.departure_time, updatedStopTime.departure_time);
            time = updatedStopTime.departure_time;
            stopTimes.add(updatedStopTime);
            logger.trace("Number of stop times: {}", stopTimes.size());
            if (stopTimeUpdate.getScheduleRelationship() == SKIPPED) {
                cancelledArrivals.add(stopTimeUpdate.getStopSequence());
                cancelledDepartures.add(stopTimeUpdate.getStopSequence());
            }
        } else if (stopTimeUpdate.getScheduleRelationship() == NO_DATA) {
        } else if (tripUpdate.getTrip().getScheduleRelationship() == GtfsRealtime.TripDescriptor.ScheduleRelationship.ADDED) {
            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(ZoneId.of(agency.agency_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(ZoneId.of(agency.agency_timezone));
            stopTime.departure_time = (int) Duration.between(departure_time.truncatedTo(ChronoUnit.DAYS), departure_time).getSeconds();
            stopTimes.add(stopTime);
            logger.trace("Number of stop times: {}", stopTimes.size());
        } else {
            throw new RuntimeException();
        }
    }
    logger.trace("Number of stop times: {}", stopTimes.size());
    // Not valid on any day. Just a template.
    BitSet validOnDay = new BitSet();
    return new GtfsReader.TripWithStopTimes(trip, stopTimes, validOnDay, cancelledArrivals, cancelledDepartures);
}
Also used : Trip(com.conveyal.gtfs.model.Trip) ArrayList(java.util.ArrayList) BitSet(java.util.BitSet) GtfsRealtime(com.google.transit.realtime.GtfsRealtime) ZonedDateTime(java.time.ZonedDateTime) GTFSFeed(com.conveyal.gtfs.GTFSFeed) Fun(org.mapdb.Fun) StopTime(com.conveyal.gtfs.model.StopTime) HashSet(java.util.HashSet) IntHashSet(com.carrotsearch.hppc.IntHashSet)

Example 3 with StopTime

use of com.conveyal.gtfs.model.StopTime in project graphhopper by graphhopper.

the class RealtimeFeed method fromProtobuf.

public static RealtimeFeed fromProtobuf(Graph graph, GtfsStorage staticGtfs, PtFlagEncoder encoder, GtfsRealtime.FeedMessage feedMessage) {
    String feedKey = "gtfs_0";
    GTFSFeed feed = staticGtfs.getGtfsFeeds().get(feedKey);
    // TODO: Require configuration of feed and agency this realtime feed is for.
    // Realtime feeds are always specific to an agency.
    Agency agency = feed.agency.values().iterator().next();
    final IntHashSet blockedEdges = new IntHashSet();
    final IntLongHashMap delaysForBoardEdges = new IntLongHashMap();
    final IntLongHashMap delaysForAlightEdges = new IntLongHashMap();
    final LinkedList<VirtualEdgeIteratorState> additionalEdges = new LinkedList<>();
    final Graph overlayGraph = new Graph() {

        int nNodes = 0;

        int firstEdge = graph.getAllEdges().getMaxId() + 1;

        final NodeAccess nodeAccess = new NodeAccess() {

            IntIntHashMap additionalNodeFields = new IntIntHashMap();

            @Override
            public int getAdditionalNodeField(int nodeId) {
                return 0;
            }

            @Override
            public void setAdditionalNodeField(int nodeId, int additionalValue) {
                additionalNodeFields.put(nodeId, additionalValue);
            }

            @Override
            public boolean is3D() {
                return false;
            }

            @Override
            public int getDimension() {
                return 0;
            }

            @Override
            public void ensureNode(int nodeId) {
            }

            @Override
            public void setNode(int nodeId, double lat, double lon) {
            }

            @Override
            public void setNode(int nodeId, double lat, double lon, double ele) {
            }

            @Override
            public double getLatitude(int nodeId) {
                return 0;
            }

            @Override
            public double getLat(int nodeId) {
                return 0;
            }

            @Override
            public double getLongitude(int nodeId) {
                return 0;
            }

            @Override
            public double getLon(int nodeId) {
                return 0;
            }

            @Override
            public double getElevation(int nodeId) {
                return 0;
            }

            @Override
            public double getEle(int nodeId) {
                return 0;
            }
        };

        @Override
        public Graph getBaseGraph() {
            return graph;
        }

        @Override
        public int getNodes() {
            return graph.getNodes() + nNodes;
        }

        @Override
        public NodeAccess getNodeAccess() {
            return nodeAccess;
        }

        @Override
        public BBox getBounds() {
            return null;
        }

        @Override
        public EdgeIteratorState edge(int a, int b) {
            return null;
        }

        @Override
        public EdgeIteratorState edge(int a, int b, double distance, boolean bothDirections) {
            int edge = firstEdge++;
            final VirtualEdgeIteratorState newEdge = new VirtualEdgeIteratorState(-1, edge, a, b, distance, 0, "", new PointList());
            final VirtualEdgeIteratorState reverseNewEdge = new VirtualEdgeIteratorState(-1, edge, b, a, distance, 0, "", new PointList());
            newEdge.setReverseEdge(reverseNewEdge);
            reverseNewEdge.setReverseEdge(newEdge);
            additionalEdges.push(newEdge);
            return newEdge;
        }

        @Override
        public EdgeIteratorState getEdgeIteratorState(int edgeId, int adjNode) {
            return null;
        }

        @Override
        public AllEdgesIterator getAllEdges() {
            return null;
        }

        @Override
        public EdgeExplorer createEdgeExplorer(EdgeFilter filter) {
            return null;
        }

        @Override
        public EdgeExplorer createEdgeExplorer() {
            return graph.createEdgeExplorer();
        }

        @Override
        public Graph copyTo(Graph g) {
            return null;
        }

        @Override
        public GraphExtension getExtension() {
            throw new RuntimeException();
        }
    };
    Map<Integer, String> routes = new HashMap<>();
    Map<GtfsStorage.Validity, Integer> operatingDayPatterns = new HashMap<>(staticGtfs.getOperatingDayPatterns());
    Map<Integer, byte[]> tripDescriptors = new HashMap<>();
    Map<Integer, Integer> stopSequences = new HashMap<>();
    Map<String, int[]> boardEdgesForTrip = new HashMap<>();
    Map<String, int[]> alightEdgesForTrip = new HashMap<>();
    Map<GtfsStorage.FeedIdWithTimezone, Integer> writableTimeZones = new HashMap<>();
    GtfsStorageI gtfsStorage = new GtfsStorageI() {

        @Override
        public Map<String, Fare> getFares() {
            return null;
        }

        @Override
        public Map<GtfsStorage.Validity, Integer> getOperatingDayPatterns() {
            return operatingDayPatterns;
        }

        @Override
        public Map<GtfsStorage.FeedIdWithTimezone, Integer> getWritableTimeZones() {
            return writableTimeZones;
        }

        @Override
        public Map<Integer, byte[]> getTripDescriptors() {
            return tripDescriptors;
        }

        @Override
        public Map<Integer, Integer> getStopSequences() {
            return stopSequences;
        }

        @Override
        public Map<String, int[]> getBoardEdgesForTrip() {
            return boardEdgesForTrip;
        }

        @Override
        public Map<String, int[]> getAlightEdgesForTrip() {
            return alightEdgesForTrip;
        }

        @Override
        public Map<String, GTFSFeed> getGtfsFeeds() {
            HashMap<String, GTFSFeed> stringGTFSFeedHashMap = new HashMap<>();
            stringGTFSFeedHashMap.put(feedKey, feed);
            return stringGTFSFeedHashMap;
        }

        @Override
        public Map<String, Transfers> getTransfers() {
            return staticGtfs.getTransfers();
        }

        @Override
        public Map<String, Integer> getStationNodes() {
            return staticGtfs.getStationNodes();
        }

        @Override
        public Map<Integer, String> getRoutes() {
            return routes;
        }
    };
    final GtfsReader gtfsReader = new GtfsReader(feedKey, overlayGraph, gtfsStorage, encoder, null);
    Instant timestamp = Instant.ofEpochSecond(feedMessage.getHeader().getTimestamp());
    // FIXME
    LocalDate dateToChange = timestamp.atZone(ZoneId.of(agency.agency_timezone)).toLocalDate();
    BitSet validOnDay = new BitSet();
    LocalDate startDate = feed.calculateStats().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 -> {
        String key = GtfsStorage.tripKey(tripUpdate.getTrip().getTripId(), tripUpdate.getTrip().getStartTime());
        final int[] boardEdges = staticGtfs.getBoardEdgesForTrip().get(key);
        final int[] leaveEdges = staticGtfs.getAlightEdgesForTrip().get(key);
        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, agency, 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 = graph.getEdgeIteratorState(boardEdge, Integer.MIN_VALUE).getAdjNode();
                int timeOffset = tripUpdate.getTrip().hasStartTime() ? LocalTime.parse(tripUpdate.getTrip().getStartTime()).toSecondOfDay() : 0;
                int delayedBoardEdge = gtfsReader.addDelayedBoardEdge(ZoneId.of(agency.agency_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(ZoneId.of(agency.agency_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(ZoneId.of(agency.agency_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(ZoneId.of(agency.agency_timezone), 0, new ArrayList<>(), tripWithStopTimes, tripUpdate.getTrip());
    });
    gtfsReader.wireUpStops();
    return new RealtimeFeed(staticGtfs, feed, agency, feedMessage, blockedEdges, delaysForBoardEdges, delaysForAlightEdges, additionalEdges, tripDescriptors, stopSequences, operatingDayPatterns);
}
Also used : EdgeFilter(com.graphhopper.routing.util.EdgeFilter) Fare(com.conveyal.gtfs.model.Fare) ZonedDateTime(java.time.ZonedDateTime) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) IntIntHashMap(com.carrotsearch.hppc.IntIntHashMap) EdgeExplorer(com.graphhopper.util.EdgeExplorer) Agency(com.conveyal.gtfs.model.Agency) NO_DATA(com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate.ScheduleRelationship.NO_DATA) Duration(java.time.Duration) Map(java.util.Map) LocalTime(java.time.LocalTime) Graph(com.graphhopper.storage.Graph) StreamSupport(java.util.stream.StreamSupport) IntLongHashMap(com.carrotsearch.hppc.IntLongHashMap) LinkedList(java.util.LinkedList) VirtualEdgeIteratorState(com.graphhopper.routing.VirtualEdgeIteratorState) GtfsRealtime(com.google.transit.realtime.GtfsRealtime) Logger(org.slf4j.Logger) EdgeIteratorState(com.graphhopper.util.EdgeIteratorState) BBox(com.graphhopper.util.shapes.BBox) GTFSFeed(com.conveyal.gtfs.GTFSFeed) SKIPPED(com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate.ScheduleRelationship.SKIPPED) IntHashSet(com.carrotsearch.hppc.IntHashSet) Set(java.util.Set) Instant(java.time.Instant) PointList(com.graphhopper.util.PointList) Collectors(java.util.stream.Collectors) ZoneId(java.time.ZoneId) Fun(org.mapdb.Fun) DAYS(java.time.temporal.ChronoUnit.DAYS) List(java.util.List) ChronoUnit(java.time.temporal.ChronoUnit) NodeAccess(com.graphhopper.storage.NodeAccess) StopTime(com.conveyal.gtfs.model.StopTime) Trip(com.conveyal.gtfs.model.Trip) LocalDate(java.time.LocalDate) GraphExtension(com.graphhopper.storage.GraphExtension) Optional(java.util.Optional) BitSet(java.util.BitSet) Collections(java.util.Collections) AllEdgesIterator(com.graphhopper.routing.util.AllEdgesIterator) PointList(com.graphhopper.util.PointList) HashMap(java.util.HashMap) IntIntHashMap(com.carrotsearch.hppc.IntIntHashMap) IntLongHashMap(com.carrotsearch.hppc.IntLongHashMap) IntHashSet(com.carrotsearch.hppc.IntHashSet) LocalDate(java.time.LocalDate) IntLongHashMap(com.carrotsearch.hppc.IntLongHashMap) ZonedDateTime(java.time.ZonedDateTime) GTFSFeed(com.conveyal.gtfs.GTFSFeed) StopTime(com.conveyal.gtfs.model.StopTime) Instant(java.time.Instant) BitSet(java.util.BitSet) LinkedList(java.util.LinkedList) GtfsRealtime(com.google.transit.realtime.GtfsRealtime) Graph(com.graphhopper.storage.Graph) NodeAccess(com.graphhopper.storage.NodeAccess) IntIntHashMap(com.carrotsearch.hppc.IntIntHashMap) EdgeFilter(com.graphhopper.routing.util.EdgeFilter) Fun(org.mapdb.Fun) Trip(com.conveyal.gtfs.model.Trip) Agency(com.conveyal.gtfs.model.Agency) VirtualEdgeIteratorState(com.graphhopper.routing.VirtualEdgeIteratorState) Fare(com.conveyal.gtfs.model.Fare)

Example 4 with StopTime

use of com.conveyal.gtfs.model.StopTime in project graphhopper by graphhopper.

the class RealtimeFeed method toTripWithStopTimes.

public static GtfsReader.TripWithStopTimes toTripWithStopTimes(GTFSFeed feed, GtfsRealtime.TripUpdate tripUpdate) {
    ZoneId timezone = ZoneId.of(feed.agency.values().stream().findFirst().get().agency_timezone);
    logger.trace("{}", tripUpdate.getTrip());
    final List<StopTime> stopTimes = new ArrayList<>();
    Set<Integer> cancelledArrivals = new HashSet<>();
    Set<Integer> cancelledDepartures = new HashSet<>();
    Trip originalTrip = feed.trips.get(tripUpdate.getTrip().getTripId());
    Trip trip = new Trip();
    if (originalTrip != null) {
        trip.trip_id = originalTrip.trip_id;
        trip.route_id = originalTrip.route_id;
    } else {
        trip.trip_id = tripUpdate.getTrip().getTripId();
        trip.route_id = tripUpdate.getTrip().getRouteId();
    }
    int delay = 0;
    int time = -1;
    List<GtfsRealtime.TripUpdate.StopTimeUpdate> stopTimeUpdateListWithSentinel = new ArrayList<>(tripUpdate.getStopTimeUpdateList());
    Iterable<StopTime> interpolatedStopTimesForTrip;
    try {
        interpolatedStopTimesForTrip = feed.getInterpolatedStopTimesForTrip(tripUpdate.getTrip().getTripId());
    } catch (GTFSFeed.FirstAndLastStopsDoNotHaveTimes firstAndLastStopsDoNotHaveTimes) {
        throw new RuntimeException(firstAndLastStopsDoNotHaveTimes);
    }
    int stopSequenceCeiling = Math.max(stopTimeUpdateListWithSentinel.isEmpty() ? 0 : stopTimeUpdateListWithSentinel.get(stopTimeUpdateListWithSentinel.size() - 1).getStopSequence(), StreamSupport.stream(interpolatedStopTimesForTrip.spliterator(), false).mapToInt(stopTime -> stopTime.stop_sequence).max().orElse(0)) + 1;
    stopTimeUpdateListWithSentinel.add(GtfsRealtime.TripUpdate.StopTimeUpdate.newBuilder().setStopSequence(stopSequenceCeiling).setScheduleRelationship(NO_DATA).build());
    for (GtfsRealtime.TripUpdate.StopTimeUpdate stopTimeUpdate : stopTimeUpdateListWithSentinel) {
        int nextStopSequence = stopTimes.isEmpty() ? 1 : stopTimes.get(stopTimes.size() - 1).stop_sequence + 1;
        for (int i = nextStopSequence; i < stopTimeUpdate.getStopSequence(); i++) {
            StopTime previousOriginalStopTime = feed.stop_times.get(new Fun.Tuple2(tripUpdate.getTrip().getTripId(), i));
            if (previousOriginalStopTime == null) {
                // This can and does happen. Stop sequence numbers can be left out.
                continue;
            }
            StopTime updatedPreviousStopTime = previousOriginalStopTime.clone();
            updatedPreviousStopTime.arrival_time = Math.max(previousOriginalStopTime.arrival_time + delay, time);
            logger.trace("stop_sequence {} scheduled arrival {} updated arrival {}", i, previousOriginalStopTime.arrival_time, updatedPreviousStopTime.arrival_time);
            time = updatedPreviousStopTime.arrival_time;
            updatedPreviousStopTime.departure_time = Math.max(previousOriginalStopTime.departure_time + delay, time);
            logger.trace("stop_sequence {} scheduled departure {} updated departure {}", i, previousOriginalStopTime.departure_time, updatedPreviousStopTime.departure_time);
            time = updatedPreviousStopTime.departure_time;
            stopTimes.add(updatedPreviousStopTime);
            logger.trace("Number of stop times: {}", stopTimes.size());
        }
        final StopTime originalStopTime = feed.stop_times.get(new Fun.Tuple2(tripUpdate.getTrip().getTripId(), stopTimeUpdate.getStopSequence()));
        if (originalStopTime != null) {
            StopTime updatedStopTime = originalStopTime.clone();
            if (stopTimeUpdate.getScheduleRelationship() == NO_DATA) {
                delay = 0;
            }
            if (stopTimeUpdate.hasArrival()) {
                delay = stopTimeUpdate.getArrival().getDelay();
            }
            updatedStopTime.arrival_time = Math.max(originalStopTime.arrival_time + delay, time);
            logger.trace("stop_sequence {} scheduled arrival {} updated arrival {}", stopTimeUpdate.getStopSequence(), originalStopTime.arrival_time, updatedStopTime.arrival_time);
            time = updatedStopTime.arrival_time;
            if (stopTimeUpdate.hasDeparture()) {
                delay = stopTimeUpdate.getDeparture().getDelay();
            }
            updatedStopTime.departure_time = Math.max(originalStopTime.departure_time + delay, time);
            logger.trace("stop_sequence {} scheduled departure {} updated departure {}", stopTimeUpdate.getStopSequence(), originalStopTime.departure_time, updatedStopTime.departure_time);
            time = updatedStopTime.departure_time;
            stopTimes.add(updatedStopTime);
            logger.trace("Number of stop times: {}", stopTimes.size());
            if (stopTimeUpdate.getScheduleRelationship() == SKIPPED) {
                cancelledArrivals.add(stopTimeUpdate.getStopSequence());
                cancelledDepartures.add(stopTimeUpdate.getStopSequence());
            }
        } else if (stopTimeUpdate.getScheduleRelationship() == NO_DATA) {
        } else if (tripUpdate.getTrip().getScheduleRelationship() == GtfsRealtime.TripDescriptor.ScheduleRelationship.ADDED) {
            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();
            stopTimes.add(stopTime);
            logger.trace("Number of stop times: {}", stopTimes.size());
        } else {
            // http://localhost:3000/route?point=45.518526513612244%2C-122.68612861633302&point=45.52908004573869%2C-122.6862144470215&weighting=fastest&pt.earliest_departure_time=2018-08-24T16%3A51%3A20Z&arrive_by=false&pt.max_walk_distance_per_leg=10000&pt.limit_solutions=4&locale=en-US&vehicle=pt&elevation=false&use_miles=false&points_encoded=false&pt.profile=true
            throw new RuntimeException();
        }
    }
    logger.trace("Number of stop times: {}", stopTimes.size());
    // Not valid on any day. Just a template.
    BitSet validOnDay = new BitSet();
    return new GtfsReader.TripWithStopTimes(trip, stopTimes, validOnDay, cancelledArrivals, cancelledDepartures);
}
Also used : Trip(com.conveyal.gtfs.model.Trip) IntArrayList(com.carrotsearch.hppc.IntArrayList) GtfsRealtime(com.google.transit.realtime.GtfsRealtime) GTFSFeed(com.conveyal.gtfs.GTFSFeed) Fun(org.mapdb.Fun) StopTime(com.conveyal.gtfs.model.StopTime) IntHashSet(com.carrotsearch.hppc.IntHashSet)

Example 5 with StopTime

use of com.conveyal.gtfs.model.StopTime in project graphhopper by graphhopper.

the class RealtimeFeed method findLeaveEdgesForTrip.

private static int[] findLeaveEdgesForTrip(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().backEdgesAround(station).spliterator(), false).flatMap(e -> StreamSupport.stream(staticGtfs.getPtGraph().backEdgesAround(e.getAdjNode()).spliterator(), false)).flatMap(e -> StreamSupport.stream(staticGtfs.getPtGraph().backEdgesAround(e.getAdjNode()).spliterator(), false)).filter(e -> e.getType() == GtfsStorage.EdgeType.ALIGHT).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 -> alightForBaseNode(staticGtfs, e));
    return collectWithPadding(boardEdges);
}
Also used : IntStream(java.util.stream.IntStream) java.util(java.util) LoggerFactory(org.slf4j.LoggerFactory) GraphHopperStorage(com.graphhopper.storage.GraphHopperStorage) java.time(java.time) NO_DATA(com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate.ScheduleRelationship.NO_DATA) IntArrayList(com.carrotsearch.hppc.IntArrayList) Frequency(com.conveyal.gtfs.model.Frequency) StreamSupport(java.util.stream.StreamSupport) IntLongHashMap(com.carrotsearch.hppc.IntLongHashMap) OutputStream(java.io.OutputStream) GtfsRealtime(com.google.transit.realtime.GtfsRealtime) Logger(org.slf4j.Logger) GTFSFeed(com.conveyal.gtfs.GTFSFeed) SKIPPED(com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate.ScheduleRelationship.SKIPPED) IntHashSet(com.carrotsearch.hppc.IntHashSet) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) Fun(org.mapdb.Fun) DAYS(java.time.temporal.ChronoUnit.DAYS) ChronoUnit(java.time.temporal.ChronoUnit) Stream(java.util.stream.Stream) StopTime(com.conveyal.gtfs.model.StopTime) Trip(com.conveyal.gtfs.model.Trip) Trip(com.conveyal.gtfs.model.Trip) StopTime(com.conveyal.gtfs.model.StopTime)

Aggregations

StopTime (com.conveyal.gtfs.model.StopTime)9 Trip (com.conveyal.gtfs.model.Trip)8 Fun (org.mapdb.Fun)8 GTFSFeed (com.conveyal.gtfs.GTFSFeed)7 GtfsRealtime (com.google.transit.realtime.GtfsRealtime)7 IntArrayList (com.carrotsearch.hppc.IntArrayList)6 IntHashSet (com.carrotsearch.hppc.IntHashSet)6 DAYS (java.time.temporal.ChronoUnit.DAYS)5 Collectors (java.util.stream.Collectors)5 Logger (org.slf4j.Logger)5 LoggerFactory (org.slf4j.LoggerFactory)5 IntLongHashMap (com.carrotsearch.hppc.IntLongHashMap)4 Frequency (com.conveyal.gtfs.model.Frequency)4 NO_DATA (com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate.ScheduleRelationship.NO_DATA)4 SKIPPED (com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate.ScheduleRelationship.SKIPPED)4 EdgeIteratorState (com.graphhopper.util.EdgeIteratorState)4 ChronoUnit (java.time.temporal.ChronoUnit)4 StreamSupport (java.util.stream.StreamSupport)4 Stop (com.conveyal.gtfs.model.Stop)3 GraphHopperStorage (com.graphhopper.storage.GraphHopperStorage)3