use of com.conveyal.gtfs.model.Stop in project graphhopper by graphhopper.
the class GtfsReader method wireUpStops.
void wireUpStops() {
for (Stop stop : feed.stops.values()) {
if (stop.location_type == 0) {
// Only stops. Not interested in parent stations for now.
int streetNode = gtfsStorage.getStationNodes().get(stop.stop_id);
if (arrivalTimelineNodes.containsKey(stop.stop_id)) {
final Map<String, List<TimelineNodeIdWithTripId>> arrivalTimelineNodesByRoute = arrivalTimelineNodes.get(stop.stop_id).stream().collect(Collectors.groupingBy(t -> t.routeId));
arrivalTimelineNodesByRoute.forEach((routeId, timelineNodesWithTripId) -> {
nodeAccess.setNode(i++, stop.stop_lat, stop.stop_lon);
int stopExitNode = i - 1;
nodeAccess.setAdditionalNodeField(stopExitNode, NodeType.STOP_EXIT_NODE.ordinal());
EdgeIteratorState exitEdge = graph.edge(stopExitNode, streetNode, 0.0, false);
setEdgeType(exitEdge, GtfsStorage.EdgeType.EXIT_PT);
exitEdge.setName(stop.stop_name);
gtfsStorage.getRoutes().put(exitEdge.getEdge(), routeId);
NavigableSet<Fun.Tuple2<Integer, Integer>> timeNodes = sorted(timelineNodesWithTripId);
wireUpAndAndConnectArrivalTimeline(stop, routeId, stopExitNode, timeNodes);
});
}
if (departureTimelineNodes.containsKey(stop.stop_id)) {
final Map<String, List<TimelineNodeIdWithTripId>> departureTimelineNodesByRoute = departureTimelineNodes.get(stop.stop_id).stream().collect(Collectors.groupingBy(t -> t.routeId));
departureTimelineNodesByRoute.forEach((routeId, timelineNodesWithTripId) -> {
nodeAccess.setNode(i++, stop.stop_lat, stop.stop_lon);
int stopEnterNode = i - 1;
nodeAccess.setAdditionalNodeField(stopEnterNode, NodeType.STOP_ENTER_NODE.ordinal());
EdgeIteratorState entryEdge = graph.edge(streetNode, stopEnterNode, 0.0, false);
setEdgeType(entryEdge, GtfsStorage.EdgeType.ENTER_PT);
entryEdge.setName(stop.stop_name);
NavigableSet<Fun.Tuple2<Integer, Integer>> timeNodes = sorted(timelineNodesWithTripId);
wireUpAndAndConnectDepartureTimeline(stop, routeId, stopEnterNode, timeNodes);
});
}
}
}
insertTransfers();
}
use of com.conveyal.gtfs.model.Stop 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.conveyal.gtfs.model.Stop in project graphhopper by graphhopper.
the class PtIsochroneResource method doGet.
@GET
@Produces({ MediaType.APPLICATION_JSON })
public Response doGet(@QueryParam("point") GHLocationParam sourceParam, @QueryParam("time_limit") @DefaultValue("600") long seconds, @QueryParam("reverse_flow") @DefaultValue("false") boolean reverseFlow, @QueryParam("pt.earliest_departure_time") @NotNull OffsetDateTimeParam departureTimeParam, @QueryParam("pt.blocked_route_types") @DefaultValue("0") int blockedRouteTypes, @QueryParam("result") @DefaultValue("multipolygon") String format) {
Instant initialTime = departureTimeParam.get().toInstant();
GHLocation location = sourceParam.get();
double targetZ = seconds * 1000;
GeometryFactory geometryFactory = new GeometryFactory();
final FlagEncoder footEncoder = encodingManager.getEncoder("foot");
final Weighting weighting = new FastestWeighting(footEncoder);
DefaultSnapFilter snapFilter = new DefaultSnapFilter(weighting, graphHopperStorage.getEncodingManager().getBooleanEncodedValue(Subnetwork.key("foot")));
PtLocationSnapper.Result snapResult = new PtLocationSnapper(graphHopperStorage, locationIndex, gtfsStorage).snapAll(Arrays.asList(location), Arrays.asList(snapFilter));
GraphExplorer graphExplorer = new GraphExplorer(snapResult.queryGraph, gtfsStorage.getPtGraph(), weighting, gtfsStorage, RealtimeFeed.empty(), reverseFlow, false, false, 5.0, reverseFlow, blockedRouteTypes);
MultiCriteriaLabelSetting router = new MultiCriteriaLabelSetting(graphExplorer, reverseFlow, false, false, 0, Collections.emptyList());
Map<Coordinate, Double> z1 = new HashMap<>();
NodeAccess nodeAccess = snapResult.queryGraph.getNodeAccess();
for (Label label : router.calcLabels(snapResult.nodes.get(0), initialTime)) {
if (!((label.currentTime - initialTime.toEpochMilli()) * (reverseFlow ? -1 : 1) <= targetZ)) {
break;
}
if (label.node.streetNode != -1) {
Coordinate nodeCoordinate = new Coordinate(nodeAccess.getLon(label.node.streetNode), nodeAccess.getLat(label.node.streetNode));
z1.merge(nodeCoordinate, (double) (label.currentTime - initialTime.toEpochMilli()) * (reverseFlow ? -1 : 1), Math::min);
} else if (label.edge != null && (label.edge.getType() == GtfsStorage.EdgeType.EXIT_PT || label.edge.getType() == GtfsStorage.EdgeType.ENTER_PT)) {
GtfsStorage.PlatformDescriptor platformDescriptor = label.edge.getPlatformDescriptor();
Stop stop = gtfsStorage.getGtfsFeeds().get(platformDescriptor.feed_id).stops.get(platformDescriptor.stop_id);
Coordinate nodeCoordinate = new Coordinate(stop.stop_lon, stop.stop_lat);
z1.merge(nodeCoordinate, (double) (label.currentTime - initialTime.toEpochMilli()) * (reverseFlow ? -1 : 1), Math::min);
}
}
if (format.equals("multipoint")) {
MultiPoint exploredPoints = geometryFactory.createMultiPointFromCoords(z1.keySet().toArray(new Coordinate[0]));
return wrap(exploredPoints);
} else {
MultiPoint exploredPoints = geometryFactory.createMultiPointFromCoords(z1.keySet().toArray(new Coordinate[0]));
// Get at least all nodes within our bounding box (I think convex hull would be enough.)
// I think then we should have all possible encroaching points. (Proof needed.)
locationIndex.query(BBox.fromEnvelope(exploredPoints.getEnvelopeInternal()), edgeId -> {
EdgeIteratorState edge = snapResult.queryGraph.getEdgeIteratorStateForKey(edgeId * 2);
z1.merge(new Coordinate(nodeAccess.getLon(edge.getBaseNode()), nodeAccess.getLat(edge.getBaseNode())), Double.MAX_VALUE, Math::min);
z1.merge(new Coordinate(nodeAccess.getLon(edge.getAdjNode()), nodeAccess.getLat(edge.getAdjNode())), Double.MAX_VALUE, Math::min);
});
exploredPoints = geometryFactory.createMultiPointFromCoords(z1.keySet().toArray(new Coordinate[0]));
CoordinateList siteCoords = DelaunayTriangulationBuilder.extractUniqueCoordinates(exploredPoints);
List<ConstraintVertex> constraintVertices = new ArrayList<>();
for (Object siteCoord : siteCoords) {
Coordinate coord = (Coordinate) siteCoord;
constraintVertices.add(new ConstraintVertex(coord));
}
ConformingDelaunayTriangulator cdt = new ConformingDelaunayTriangulator(constraintVertices, JTS_TOLERANCE);
cdt.setConstraints(new ArrayList(), new ArrayList());
cdt.formInitialDelaunay();
QuadEdgeSubdivision tin = cdt.getSubdivision();
for (Vertex vertex : (Collection<Vertex>) tin.getVertices(true)) {
if (tin.isFrameVertex(vertex)) {
vertex.setZ(Double.MAX_VALUE);
} else {
Double aDouble = z1.get(vertex.getCoordinate());
if (aDouble != null) {
vertex.setZ(aDouble);
} else {
vertex.setZ(Double.MAX_VALUE);
}
}
}
ReadableTriangulation triangulation = ReadableTriangulation.wrap(tin);
ContourBuilder contourBuilder = new ContourBuilder(triangulation);
MultiPolygon isoline = contourBuilder.computeIsoline(targetZ, triangulation.getEdges());
// debugging tool
if (format.equals("triangulation")) {
Response response = new Response();
for (Vertex vertex : (Collection<Vertex>) tin.getVertices(true)) {
JsonFeature feature = new JsonFeature();
feature.setGeometry(geometryFactory.createPoint(vertex.getCoordinate()));
HashMap<String, Object> properties = new HashMap<>();
properties.put("z", vertex.getZ());
feature.setProperties(properties);
response.polygons.add(feature);
}
for (QuadEdge edge : (Collection<QuadEdge>) tin.getPrimaryEdges(false)) {
JsonFeature feature = new JsonFeature();
feature.setGeometry(edge.toLineSegment().toGeometry(geometryFactory));
HashMap<String, Object> properties = new HashMap<>();
feature.setProperties(properties);
response.polygons.add(feature);
}
JsonFeature feature = new JsonFeature();
feature.setGeometry(isoline);
HashMap<String, Object> properties = new HashMap<>();
properties.put("z", targetZ);
feature.setProperties(properties);
response.polygons.add(feature);
response.info.copyrights.addAll(ResponsePathSerializer.COPYRIGHTS);
return response;
} else {
return wrap(isoline);
}
}
}
use of com.conveyal.gtfs.model.Stop in project graphhopper by graphhopper.
the class Transfers method explodeTransfers.
private Stream<Transfer> explodeTransfers(GTFSFeed feed) {
return feed.transfers.values().stream().flatMap(t -> {
Stop fromStop = feed.stops.get(t.from_stop_id);
if (fromStop.location_type == 1) {
return feed.stops.values().stream().filter(platform -> fromStop.stop_id.equals(platform.parent_station)).map(platform -> {
Transfer clone = t.clone();
clone.from_stop_id = platform.stop_id;
return clone;
});
} else {
return Stream.of(t);
}
}).flatMap(t -> {
Stop toStop = feed.stops.get(t.to_stop_id);
if (toStop.location_type == 1) {
return feed.stops.values().stream().filter(platform -> toStop.stop_id.equals(platform.parent_station)).map(platform -> {
Transfer clone = t.clone();
clone.to_stop_id = platform.stop_id;
return clone;
});
} else {
return Stream.of(t);
}
});
}
use of com.conveyal.gtfs.model.Stop in project graphhopper by graphhopper.
the class TripFromLabel method createResponsePath.
ResponsePath createResponsePath(Translation tr, PointList waypoints, Graph queryGraph, Weighting accessWeighting, Weighting egressWeighting, List<Label.Transition> solution, List<String> requestedPathDetails) {
final List<List<Label.Transition>> partitions = parsePathToPartitions(solution);
final List<Trip.Leg> legs = new ArrayList<>();
for (int i = 0; i < partitions.size(); i++) {
legs.addAll(parsePartitionToLegs(partitions.get(i), queryGraph, i == partitions.size() - 1 ? egressWeighting : accessWeighting, tr, requestedPathDetails));
}
if (legs.size() > 1 && legs.get(0) instanceof Trip.WalkLeg) {
final Trip.WalkLeg accessLeg = (Trip.WalkLeg) legs.get(0);
legs.set(0, new Trip.WalkLeg(accessLeg.departureLocation, new Date(legs.get(1).getDepartureTime().getTime() - (accessLeg.getArrivalTime().getTime() - accessLeg.getDepartureTime().getTime())), accessLeg.geometry, accessLeg.distance, accessLeg.instructions, accessLeg.details, legs.get(1).getDepartureTime()));
}
if (legs.size() > 1 && legs.get(legs.size() - 1) instanceof Trip.WalkLeg) {
final Trip.WalkLeg egressLeg = (Trip.WalkLeg) legs.get(legs.size() - 1);
legs.set(legs.size() - 1, new Trip.WalkLeg(egressLeg.departureLocation, legs.get(legs.size() - 2).getArrivalTime(), egressLeg.geometry, egressLeg.distance, egressLeg.instructions, egressLeg.details, new Date(legs.get(legs.size() - 2).getArrivalTime().getTime() + (egressLeg.getArrivalTime().getTime() - egressLeg.getDepartureTime().getTime()))));
}
ResponsePath path = new ResponsePath();
path.setWaypoints(waypoints);
path.getLegs().addAll(legs);
final InstructionList instructions = new InstructionList(tr);
final PointList pointsList = new PointList();
Map<String, List<PathDetail>> pathDetails = new HashMap<>();
for (int i = 0; i < path.getLegs().size(); ++i) {
Trip.Leg leg = path.getLegs().get(i);
if (leg instanceof Trip.WalkLeg) {
final Trip.WalkLeg walkLeg = ((Trip.WalkLeg) leg);
List<Instruction> theseInstructions = walkLeg.instructions.subList(0, i < path.getLegs().size() - 1 ? walkLeg.instructions.size() - 1 : walkLeg.instructions.size());
int previousPointsCount = pointsList.size();
for (Instruction instruction : theseInstructions) {
pointsList.add(instruction.getPoints());
}
instructions.addAll(theseInstructions);
Map<String, List<PathDetail>> shiftedLegPathDetails = shift(((Trip.WalkLeg) leg).details, previousPointsCount);
shiftedLegPathDetails.forEach((k, v) -> pathDetails.merge(k, shiftedLegPathDetails.get(k), (a, b) -> Lists.newArrayList(Iterables.concat(a, b))));
} else if (leg instanceof Trip.PtLeg) {
final Trip.PtLeg ptLeg = ((Trip.PtLeg) leg);
final PointList pl;
if (!ptLeg.isInSameVehicleAsPrevious) {
pl = new PointList();
final Instruction departureInstruction = new Instruction(Instruction.PT_START_TRIP, ptLeg.trip_headsign, pl);
departureInstruction.setDistance(leg.getDistance());
departureInstruction.setTime(ptLeg.travelTime);
instructions.add(departureInstruction);
} else {
pl = instructions.get(instructions.size() - 2).getPoints();
}
pl.add(ptLeg.stops.get(0).geometry.getY(), ptLeg.stops.get(0).geometry.getX());
pointsList.add(ptLeg.stops.get(0).geometry.getY(), ptLeg.stops.get(0).geometry.getX());
for (Trip.Stop stop : ptLeg.stops.subList(0, ptLeg.stops.size() - 1)) {
pl.add(stop.geometry.getY(), stop.geometry.getX());
pointsList.add(stop.geometry.getY(), stop.geometry.getX());
}
final PointList arrivalPointList = new PointList();
final Trip.Stop arrivalStop = ptLeg.stops.get(ptLeg.stops.size() - 1);
arrivalPointList.add(arrivalStop.geometry.getY(), arrivalStop.geometry.getX());
pointsList.add(arrivalStop.geometry.getY(), arrivalStop.geometry.getX());
Instruction arrivalInstruction = new Instruction(Instruction.PT_END_TRIP, arrivalStop.stop_name, arrivalPointList);
if (ptLeg.isInSameVehicleAsPrevious) {
instructions.set(instructions.size() - 1, arrivalInstruction);
} else {
instructions.add(arrivalInstruction);
}
}
}
path.setInstructions(instructions);
path.setPoints(pointsList);
path.addPathDetails(pathDetails);
path.setDistance(path.getLegs().stream().mapToDouble(Trip.Leg::getDistance).sum());
path.setTime((legs.get(legs.size() - 1).getArrivalTime().toInstant().toEpochMilli() - legs.get(0).getDepartureTime().toInstant().toEpochMilli()));
path.setNumChanges((int) path.getLegs().stream().filter(l -> l instanceof Trip.PtLeg).filter(l -> !((Trip.PtLeg) l).isInSameVehicleAsPrevious).count() - 1);
com.graphhopper.gtfs.fare.Trip faresTrip = new com.graphhopper.gtfs.fare.Trip();
path.getLegs().stream().filter(leg -> leg instanceof Trip.PtLeg).map(leg -> (Trip.PtLeg) leg).findFirst().ifPresent(firstPtLeg -> {
LocalDateTime firstPtDepartureTime = GtfsHelper.localDateTimeFromDate(firstPtLeg.getDepartureTime());
path.getLegs().stream().filter(leg -> leg instanceof Trip.PtLeg).map(leg -> (Trip.PtLeg) leg).map(ptLeg -> {
final GTFSFeed gtfsFeed = gtfsStorage.getGtfsFeeds().get(ptLeg.feed_id);
return new com.graphhopper.gtfs.fare.Trip.Segment(ptLeg.feed_id, ptLeg.route_id, Duration.between(firstPtDepartureTime, GtfsHelper.localDateTimeFromDate(ptLeg.getDepartureTime())).getSeconds(), gtfsFeed.stops.get(ptLeg.stops.get(0).stop_id).zone_id, gtfsFeed.stops.get(ptLeg.stops.get(ptLeg.stops.size() - 1).stop_id).zone_id, ptLeg.stops.stream().map(s -> gtfsFeed.stops.get(s.stop_id).zone_id).collect(Collectors.toSet()));
}).forEach(faresTrip.segments::add);
Fares.cheapestFare(gtfsStorage.getFares(), faresTrip).ifPresent(amount -> path.setFare(amount.getAmount()));
});
return path;
}
Aggregations