org.opentripplanner.profile.StopTreeCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
package org.opentripplanner.profile;
import com.beust.jcommander.internal.Maps;
import org.opentripplanner.routing.algorithm.AStar;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.core.TraverseMode;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.graph.Vertex;
import org.opentripplanner.routing.spt.DominanceFunction;
import org.opentripplanner.routing.spt.ShortestPathTree;
import org.opentripplanner.routing.vertextype.TransitStop;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
/**
* Keeps travel distances from all transit stops in a particular Graph to their nearby street nodes.
* This allows us to propagate travel times out from transit to streets much faster in one-to-many analyst queries.
* The StopTreeCache has a fixed distance cutoff, so will be unable to provide distance information for vertices beyond
* that cutoff distance.
*/
public class StopTreeCache {
private static final Logger LOG = LoggerFactory.getLogger(StopTreeCache.class);
final int maxWalkMeters;
// Flattened 2D array of (streetVertexIndex, distanceFromStop) for each TransitStop
public final Map distancesForStop = Maps.newHashMap();
public StopTreeCache (Graph graph, int maxWalkMeters) {
this.maxWalkMeters = maxWalkMeters;
LOG.info("Caching distances to nearby street intersections from each transit stop...");
graph.index.stopVertexForStop.values().parallelStream().forEach(tstop -> {
RoutingRequest rr = new RoutingRequest(TraverseMode.WALK);
rr.batch = (true);
rr.setRoutingContext(graph, tstop, tstop);
AStar astar = new AStar();
rr.longDistance = true;
rr.setNumItineraries(1);
// since we're storing distances and later using them to optimize
// (in the profile propagation code we optimize on distance / walkSpeed
// not the actual time including turn costs etc.),
// we need to optimize on distance here as well.
rr.maxWalkDistance = maxWalkMeters;
rr.softWalkLimiting = false;
rr.dominanceFunction = new DominanceFunction.LeastWalk();
ShortestPathTree spt = astar.getShortestPathTree(rr, 5); // timeout in seconds
// Copy vertex indices and distances into a flattened 2D array
int[] distances = new int[spt.getVertexCount() * 2];
int i = 0;
for (Vertex vertex : spt.getVertices()) {
State state = spt.getState(vertex);
if (state == null)
continue;
distances[i++] = vertex.getIndex();
distances[i++] = (int) state.getWalkDistance();
}
rr.cleanup();
synchronized (distancesForStop) {
distancesForStop.put(tstop, distances);
}
});
LOG.info("Done caching distances to nearby street intersections from each transit stop.");
}
/**
* Given a travel time to a transit stop, fill in the array with minimum travel times to all nearby street vertices.
* This function is meant to be called repeatedly on multiple transit stops, accumulating minima
* into the same targetArray.
*/
public void propagateStop(TransitStop transitStop, int baseTimeSeconds, double walkSpeed, int[] targetArray) {
// Iterate over street intersections in the vicinity of this particular transit stop.
// Shift the time range at this transit stop, merging it into that for all reachable street intersections.
int[] distances = distancesForStop.get(transitStop);
int v = 0;
while (v < distances.length) {
// Unravel flattened 2D array
int vertexIndex = distances[v++];
int distance = distances[v++];
// distance in meters over walkspeed in meters per second --> seconds
int egressWalkTimeSeconds = (int) (distance / walkSpeed);
int propagated_time = baseTimeSeconds + egressWalkTimeSeconds;
int existing_min = targetArray[vertexIndex];
if (existing_min == 0 || existing_min > propagated_time) {
targetArray[vertexIndex] = propagated_time;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy