use of org.opentripplanner.util.ProgressTracker in project OpenTripPlanner by opentripplanner.
the class GeometryAndBlockProcessor method run.
/**
* Generate the edges. Assumes that there are already vertices in the graph for the stops.
*/
@SuppressWarnings("Convert2MethodRef")
public void run(Graph graph, DataImportIssueStore issueStore) {
this.issueStore = issueStore;
fareServiceFactory.processGtfs(transitService);
/* Assign 0-based numeric codes to all GTFS service IDs. */
for (FeedScopedId serviceId : transitService.getAllServiceIds()) {
// TODO: FIX Service code collision for multiple feeds.
graph.getServiceCodes().put(serviceId, graph.getServiceCodes().size());
}
LOG.info("Processing geometries and blocks on graph...");
// Wwe have to build the hop geometries before we throw away the modified stopTimes, saving
// only the tripTimes (which don't have enough information to build a geometry). So we keep
// them here. In the current design, a trip pattern does not have a single geometry, but
// one per hop, so we store them in an array.
Map<TripPattern, LineString[]> geometriesByTripPattern = Maps.newHashMap();
Collection<TripPattern> tripPatterns = transitService.getTripPatterns();
/* Generate unique short IDs for all the TableTripPatterns. */
if (!TripPattern.idsAreUniqueAndNotNull(tripPatterns)) {
TripPattern.generateUniqueIds(tripPatterns);
}
/* Generate unique human-readable names for all the TableTripPatterns. */
TripPattern.generateUniqueNames(tripPatterns, issueStore);
/* Loop over all new TripPatterns, creating edges, setting the service codes and geometries, etc. */
ProgressTracker progress = ProgressTracker.track("Generate TripPattern geometries", 100, tripPatterns.size());
LOG.info(progress.startMessage());
for (TripPattern tripPattern : tripPatterns) {
for (Trip trip : tripPattern.getTrips()) {
// there would be a trip pattern with no geometry yet because it failed some of these tests
if (!geometriesByTripPattern.containsKey(tripPattern) && trip.getShapeId() != null && trip.getShapeId().getId() != null && !trip.getShapeId().getId().equals("")) {
// save the geometry to later be applied to the hops
geometriesByTripPattern.put(tripPattern, createGeometry(trip.getShapeId(), transitService.getStopTimesForTrip(trip)));
}
}
// Keep lambda! A method-ref would causes incorrect class and line number to be logged
progress.step(m -> LOG.info(m));
}
LOG.info(progress.completeMessage());
/* Loop over all new TripPatterns setting the service codes and geometries, etc. */
for (TripPattern tripPattern : tripPatterns) {
LineString[] hopGeometries = geometriesByTripPattern.get(tripPattern);
if (hopGeometries != null) {
// Make a single unified geometry, and also store the per-hop split geometries.
tripPattern.setHopGeometries(hopGeometries);
}
// TODO this could be more elegant
tripPattern.setServiceCodes(graph.getServiceCodes());
// Store the tripPattern in the Graph so it will be serialized and usable in routing.
graph.tripPatternForId.put(tripPattern.getId(), tripPattern);
}
/* Identify interlined trips and create the necessary edges. */
interline(tripPatterns, graph);
// it is already done at deserialization, but standalone mode allows using graphs without serializing them.
for (TripPattern tableTripPattern : tripPatterns) {
tableTripPattern.scheduledTimetable.finish();
}
graph.putService(FareService.class, fareServiceFactory.makeFareService());
}
use of org.opentripplanner.util.ProgressTracker in project OpenTripPlanner by opentripplanner.
the class BusRouteStreetMatcher method buildGraph.
public void buildGraph(Graph graph, HashMap<Class<?>, Object> extra, DataImportIssueStore issueStore) {
// Mapbuilder needs transit index
graph.index();
StreetMatcher matcher = new StreetMatcher(graph);
log.info("Finding corresponding street edges for trip patterns...");
// Why do we need to iterate over the routes? Why not just patterns?
Collection<Route> allRoutes = graph.index.getAllRoutes();
// Track progress
ProgressTracker progress = ProgressTracker.track("Match route to street edges", 10, allRoutes.size());
log.info(progress.startMessage());
for (Route route : allRoutes) {
for (TripPattern pattern : graph.index.getPatternsForRoute().get(route)) {
if (pattern.getMode() == TransitMode.BUS) {
/* we can only match geometry to streets on bus routes */
log.debug("Matching {}", pattern);
// that is why pattern.geometry is null in that case
if (pattern.getGeometry() == null) {
continue;
}
for (int i = 0; i < pattern.numHopGeometries(); i++) {
LineString hopGeometry = pattern.getHopGeometry(i);
List<Edge> edges = matcher.match(hopGeometry);
if (edges == null || edges.isEmpty()) {
log.warn("Could not match to street network: {}", pattern);
continue;
}
List<Coordinate> coordinates = new ArrayList<>();
for (Edge e : edges) {
coordinates.addAll(Arrays.asList(e.getGeometry().getCoordinates()));
}
Coordinate[] coordinateArray = new Coordinate[coordinates.size()];
LineString ls = GeometryUtils.getGeometryFactory().createLineString(coordinates.toArray(coordinateArray));
// Replace the hop's geometry from GTFS with that of the equivalent OSM edges.
pattern.setHopGeometry(i, ls);
}
}
}
progress.step(log::info);
}
log.info(progress.completeMessage());
}
use of org.opentripplanner.util.ProgressTracker in project OpenTripPlanner by opentripplanner.
the class FlexTripsMapper method createFlexTrips.
public static void createFlexTrips(OtpTransitServiceBuilder builder) {
TripStopTimes stopTimesByTrip = builder.getStopTimesSortedByTrip();
final int tripSize = stopTimesByTrip.size();
ProgressTracker progress = ProgressTracker.track("Create flex trips", 500, tripSize);
for (org.opentripplanner.model.Trip trip : stopTimesByTrip.keys()) {
/* Fetch the stop times for this trip. Copy the list since it's immutable. */
List<StopTime> stopTimes = new ArrayList<>(stopTimesByTrip.get(trip));
if (UnscheduledTrip.isUnscheduledTrip(stopTimes)) {
if (stopTimes.size() == 2) {
// TODO: Drop this restriction after time handling and ride times are defined
builder.getFlexTripsById().add(new UnscheduledTrip(trip, stopTimes));
}
} else if (ScheduledDeviatedTrip.isScheduledFlexTrip(stopTimes)) {
builder.getFlexTripsById().add(new ScheduledDeviatedTrip(trip, stopTimes));
} else if (hasContinuousStops(stopTimes)) {
// builder.getFlexTripsById().add(new ContinuousPickupDropOffTrip(trip, stopTimes));
}
// Keep lambda! A method-ref would causes incorrect class and line number to be logged
progress.step(m -> LOG.info(m));
}
LOG.info(progress.completeMessage());
LOG.info("Done creating flex trips. Created a total of {} trips.", builder.getFlexTripsById().size());
}
use of org.opentripplanner.util.ProgressTracker in project OpenTripPlanner by opentripplanner.
the class SimpleStreetSplitter method link.
@SuppressWarnings("Convert2MethodRef")
public <T extends Vertex> void link(Class<T> type, Function<T, DataImportIssue> unlinkedIssueMapper) {
@SuppressWarnings("unchecked") List<T> vertices = graph.getVertices().stream().filter(type::isInstance).map(it -> (T) it).collect(Collectors.toList());
String actionName = "Link " + type.getSimpleName();
if (vertices.isEmpty()) {
LOG.info("{} skiped. No such data exist.", actionName);
return;
}
ProgressTracker progress = ProgressTracker.track(actionName, 500, vertices.size());
LOG.info(progress.startMessage());
for (T v : vertices) {
// Do not link vertices, which are already linked by TransitToTaggedStopsModule
boolean alreadyLinked = v.getOutgoing().stream().anyMatch(e -> e instanceof StreetTransitLink);
if (alreadyLinked) {
continue;
}
// Do not link stops connected by pathways
if (v instanceof TransitStopVertex && ((TransitStopVertex) v).hasPathways()) {
continue;
}
if (!link(v)) {
issueStore.add(unlinkedIssueMapper.apply(v));
}
// Keep lambda! A method-ref would cause incorrect class and line number to be logged
progress.step(m -> LOG.info(m));
}
LOG.info(progress.completeMessage());
}
use of org.opentripplanner.util.ProgressTracker in project OpenTripPlanner by opentripplanner.
the class DirectTransferGenerator method buildGraph.
@Override
public void buildGraph(Graph graph, HashMap<Class<?>, Object> extra, DataImportIssueStore issueStore) {
/* Initialize graph index which is needed by the nearby stop finder. */
if (graph.index == null) {
graph.index = new GraphIndex(graph);
}
/* The linker will use streets if they are available, or straight-line distance otherwise. */
NearbyStopFinder nearbyStopFinder = new NearbyStopFinder(graph, radiusMeters);
if (nearbyStopFinder.useStreets) {
LOG.info("Creating direct transfer edges between stops using the street network from OSM...");
} else {
LOG.info("Creating direct transfer edges between stops using straight line distance (not streets)...");
}
Iterable<TransitStopVertex> stops = Iterables.filter(graph.getVertices(), TransitStopVertex.class);
ProgressTracker progress = ProgressTracker.track("Create transfer edges", 1000, Iterables.size(stops));
int nTransfersTotal = 0;
int nLinkableStops = 0;
// This could be multi-threaded, in which case we'd need to be careful about the lifecycle of NearbyStopFinder instances.
for (TransitStopVertex ts0 : stops) {
Stop stop = ts0.getStop();
LOG.debug("Linking stop '{}' {}", stop, ts0);
/* Make transfers to each nearby stop that is the closest stop on some trip pattern. */
int n = 0;
for (StopAtDistance sd : nearbyStopFinder.findNearbyStopsConsideringPatterns(ts0, false)) {
// Skip the origin stop, loop transfers are not needed.
if (sd.stop == stop) {
continue;
}
graph.transfersByStop.put(stop, new SimpleTransfer(stop, sd.stop, sd.distance, sd.edges));
n += 1;
}
if (OTPFeature.FlexRouting.isOn()) {
// from Stops to FlexStopLocations and between Stops are already covered above.
for (StopAtDistance sd : nearbyStopFinder.findNearbyStopsConsideringPatterns(ts0, true)) {
// Skip the origin stop, loop transfers are not needed.
if (sd.stop == ts0.getStop()) {
continue;
}
if (sd.stop instanceof Stop) {
continue;
}
graph.transfersByStop.put(sd.stop, new SimpleTransfer(sd.stop, ts0.getStop(), sd.distance, sd.edges));
n += 1;
}
}
LOG.debug("Linked stop {} to {} nearby stops on other patterns.", stop, n);
if (n == 0) {
issueStore.add(new StopNotLinkedForTransfers(ts0));
}
// Keep lambda! A method-ref would causes incorrect class and line number to be logged
progress.step(m -> LOG.info(m));
nTransfersTotal += n;
}
LOG.info(progress.completeMessage());
LOG.info("Done connecting stops to one another. Created a total of {} transfers from {} stops.", nTransfersTotal, nLinkableStops);
graph.hasDirectTransfers = true;
}
Aggregations