use of com.graphhopper.util.EdgeIteratorState 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);
}
use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.
the class GtfsReader method insertInboundBlockTransfers.
private void insertInboundBlockTransfers(List<TripWithStopTimeAndArrivalNode> arrivalNodes, GtfsRealtime.TripDescriptor tripDescriptor, int departureNode, StopTime stopTime, Stop stop, GtfsStorage.Validity validOn, ZoneId zoneId) {
BitSet accumulatorValidity = new BitSet(validOn.validity.size());
accumulatorValidity.or(validOn.validity);
EdgeIteratorState edge;
ListIterator<TripWithStopTimeAndArrivalNode> li = arrivalNodes.listIterator(arrivalNodes.size());
while (li.hasPrevious() && accumulatorValidity.cardinality() > 0) {
TripWithStopTimeAndArrivalNode lastTrip = li.previous();
int dwellTime = times.get(departureNode) - times.get(lastTrip.arrivalNode);
if (dwellTime >= 0 && accumulatorValidity.intersects(lastTrip.tripWithStopTimes.validOnDay)) {
BitSet blockTransferValidity = new BitSet(validOn.validity.size());
blockTransferValidity.or(validOn.validity);
blockTransferValidity.and(accumulatorValidity);
GtfsStorage.Validity blockTransferValidOn = new GtfsStorage.Validity(blockTransferValidity, zoneId, startDate);
int blockTransferValidityId;
if (gtfsStorage.getOperatingDayPatterns().containsKey(blockTransferValidOn)) {
blockTransferValidityId = gtfsStorage.getOperatingDayPatterns().get(blockTransferValidOn);
} else {
blockTransferValidityId = gtfsStorage.getOperatingDayPatterns().size();
gtfsStorage.getOperatingDayPatterns().put(blockTransferValidOn, blockTransferValidityId);
}
nodeAccess.setNode(i++, stop.stop_lat, stop.stop_lon);
nodeAccess.setAdditionalNodeField(i - 1, NodeType.INTERNAL_PT.ordinal());
edge = graph.edge(lastTrip.arrivalNode, i - 1, 0.0, false);
setEdgeType(edge, GtfsStorage.EdgeType.TRANSFER);
edge.setFlags(encoder.setTime(edge.getFlags(), dwellTime));
edge = graph.edge(i - 1, departureNode, 0.0, false);
setEdgeType(edge, GtfsStorage.EdgeType.BOARD);
edge.setFlags(encoder.setValidityId(edge.getFlags(), blockTransferValidityId));
gtfsStorage.getStopSequences().put(edge.getEdge(), stopTime.stop_sequence);
gtfsStorage.getTripDescriptors().put(edge.getEdge(), tripDescriptor.toByteArray());
accumulatorValidity.andNot(lastTrip.tripWithStopTimes.validOnDay);
}
}
}
use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.
the class GtfsReader method wireUpAndAndConnectDepartureTimeline.
private void wireUpAndAndConnectDepartureTimeline(Stop toStop, String toRouteId, int stopEnterNode, NavigableSet<Fun.Tuple2<Integer, Integer>> timeNodes) {
ZoneId zoneId = ZoneId.of(feed.agency.get(feed.routes.get(toRouteId).agency_id).agency_timezone);
int time = 0;
int prev = -1;
for (Fun.Tuple2<Integer, Integer> e : timeNodes.descendingSet()) {
EdgeIteratorState enterTimeExpandedNetworkEdge = graph.edge(stopEnterNode, e.b, 0.0, false);
enterTimeExpandedNetworkEdge.setName(toStop.stop_name);
setEdgeType(enterTimeExpandedNetworkEdge, GtfsStorage.EdgeType.ENTER_TIME_EXPANDED_NETWORK);
enterTimeExpandedNetworkEdge.setFlags(encoder.setTime(enterTimeExpandedNetworkEdge.getFlags(), e.a));
setFeedIdWithTimezone(enterTimeExpandedNetworkEdge, new GtfsStorage.FeedIdWithTimezone(id, zoneId));
if (prev != -1) {
EdgeIteratorState edge = graph.edge(e.b, prev, 0.0, false);
setEdgeType(edge, GtfsStorage.EdgeType.WAIT);
edge.setName(toStop.stop_name);
edge.setFlags(encoder.setTime(edge.getFlags(), time - e.a));
}
time = e.a;
prev = e.b;
}
if (!timeNodes.isEmpty()) {
EdgeIteratorState edge = graph.edge(timeNodes.last().b, timeNodes.first().b, 0.0, false);
int rolloverTime = 24 * 60 * 60 - timeNodes.last().a + timeNodes.first().a;
setEdgeType(edge, GtfsStorage.EdgeType.OVERNIGHT);
edge.setName(toStop.stop_name);
edge.setFlags(encoder.setTime(edge.getFlags(), rolloverTime));
}
}
use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.
the class Label method reverseEdges.
static Iterable<Transition> reverseEdges(Label leaf, GraphExplorer graph, PtFlagEncoder flagEncoder, boolean reverseEdgeFlags) {
return new Iterable<Transition>() {
@Override
public Iterator<Transition> iterator() {
return new Iterator<Transition>() {
int i = 0;
Label label = leaf;
@Override
public boolean hasNext() {
return reverseEdgeFlags ? label != null : label.parent != null;
}
@Override
public Transition next() {
if (i == 0 && !reverseEdgeFlags) {
++i;
return new Transition(label, null);
} else {
EdgeIteratorState edgeIteratorState = label.parent == null ? null : graph.getEdgeIteratorState(label.edge, label.parent.adjNode).detach(reverseEdgeFlags);
Transition transition;
if (reverseEdgeFlags) {
transition = new Transition(label, edgeIteratorState != null ? getEdgeLabel(edgeIteratorState, flagEncoder) : null);
} else {
transition = new Transition(label.parent, edgeIteratorState != null ? getEdgeLabel(edgeIteratorState, flagEncoder) : null);
}
label = label.parent;
return transition;
}
}
};
}
};
}
use of com.graphhopper.util.EdgeIteratorState 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);
}
Aggregations