* Perform an on-street search around a point with a specific mode to find nearby stops.
* @param dest : whether to search at the destination instead of the origin.
*/
private Collection<StopAtDistance> findClosestStops(final TraverseMode mode, boolean dest) {
// Make a normal OTP routing request so we can traverse edges and use GenericAStar
RoutingRequest rr = new RoutingRequest(mode);
if (mode == TraverseMode.CAR) {
//rr.kissAndRide = true; // allow car->walk transition. we are assuming that someone will drop you off.
rr.parkAndRide = true; // allow car->walk transition only at tagged park and ride facilities.
rr.modes.setWalk(true); // need to walk after dropping the car off
}
rr.from = (new GenericLocation(request.from.lat, request.from.lon));
// FIXME requires destination to be set, not necesary for analyst
rr.to = new GenericLocation(request.to.lat, request.to.lon);
rr.setArriveBy(dest);
rr.setRoutingContext(graph);
// Set batch after context, so both origin and dest vertices will be found.
rr.batch = (true);
rr.walkSpeed = request.walkSpeed;
// RR dateTime defaults to currentTime.
// If elapsed time is not capped, searches are very slow.
int minAccessTime = 0;
int maxAccessTime = request.maxWalkTime;
if (mode == TraverseMode.BICYCLE) {
rr.bikeSpeed = request.bikeSpeed;
minAccessTime = request.minBikeTime;
maxAccessTime = request.maxBikeTime;
} else if (mode == TraverseMode.CAR) {
rr.carSpeed = request.carSpeed;
minAccessTime = request.minCarTime;
maxAccessTime = request.maxCarTime;
} else {
LOG.warn("No modes matched when setting min/max travel times.");
}
long worstElapsedTimeSeconds = maxAccessTime * 60; // convert from minutes to seconds
if (dest) worstElapsedTimeSeconds *= -1;
rr.worstTime = (rr.dateTime + worstElapsedTimeSeconds);
// Note that the (forward) search is intentionally unlimited so it will reach the destination
// on-street, even though only transit boarding locations closer than req.streetDist will be used.
GenericAStar astar = new GenericAStar();
rr.setNumItineraries(1);
StopFinderTraverseVisitor visitor = new StopFinderTraverseVisitor(mode, minAccessTime * 60);
astar.setTraverseVisitor(visitor);
astar.getShortestPathTree(rr, 5); // timeout in seconds
// Save the routing context for later cleanup. We need its temporary edges to render street segments at the end.
routingContexts.add(rr.rctx);