package org.opentripplanner.analyst;
import gnu.trove.iterator.TIntIntIterator;
import gnu.trove.map.TIntIntMap;
import junit.framework.TestCase;
import junit.framework.TestResult;
import org.joda.time.LocalDate;
import org.junit.Test;
import org.opentripplanner.analyst.cluster.TaskStatistics;
import org.opentripplanner.api.parameter.QualifiedModeSet;
import org.opentripplanner.profile.ProfileRequest;
import org.opentripplanner.profile.RaptorWorkerData;
import org.opentripplanner.profile.RepeatedRaptorProfileRouter;
import org.opentripplanner.profile.TimeWindow;
import org.opentripplanner.routing.algorithm.AStar;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.core.TraverseModeSet;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.impl.DefaultStreetVertexIndexFactory;
import static org.opentripplanner.graph_builder.module.FakeGraph.*;
/**
* Test the code that finds initial transit stops.
*/
public class InitialStopsTest extends TestCase {
/** Time (in seconds) that a decrease must be greater than in order to be considered a decrease (make sure tests don't inadvertently pass due to rounding errors) */
public static final int EPSILON = 10;
/**
* Test that increasing the bike speed on a bike-to-transit search
* a) decreases or leaves unchanged all access times.
* b) allows access to a superset of the originally accessible stops.
*
* There was once a bug where bike speed was not correctly applied because we used the distance not the speed.
*/
@Test
public void testInitialStopBikeSpeedIncrease () throws Exception {
Graph g = buildGraphNoTransit();
addRegularStopGrid(g);
addTransitMultipleLines(g);
link(g);
g.index(new DefaultStreetVertexIndexFactory());
ProfileRequest req = new ProfileRequest();
req.fromLon = req.toLon = -83.0118;
req.fromLat = req.toLat = 39.9908;
req.date = new LocalDate(2015, 9, 17);
req.bikeSpeed = 4.1f;
req.walkSpeed = 1.3f;
req.fromTime = 7 * 3600;
req.toTime = 9 * 3600;
req.maxBikeTime = 20;
req.transitModes = new TraverseModeSet("TRANSIT");
req.accessModes = req.egressModes = req.directModes = new QualifiedModeSet("BICYCLE");
RaptorWorkerData data = RepeatedRaptorProfileRouter.getRaptorWorkerData(req, g, null, new TaskStatistics());
assertNotNull(data);
RepeatedRaptorProfileRouter rrpr = new RepeatedRaptorProfileRouter(g, req);
TIntIntMap initialStops1 = rrpr.findInitialStops(false, data);
assertFalse(initialStops1.isEmpty());
// let's get crazy, set bike speed really high.
req.bikeSpeed = 25f;
data = RepeatedRaptorProfileRouter.getRaptorWorkerData(req, g, null, new TaskStatistics());
assertNotNull(data);
rrpr = new RepeatedRaptorProfileRouter(g, req);
TIntIntMap initialStops2 = rrpr.findInitialStops(false, data);
// we should find decreases to at least some stops
boolean foundDecreases = false;
for (TIntIntIterator it = initialStops1.iterator(); it.hasNext();) {
it.advance();
// the reached stops from the faster search should be a superset of the reached stops from the slower search
assertTrue(initialStops2.containsKey(it.key()));
assertTrue("Found increase in travel time to stop", initialStops2.get(it.key()) <= it.value());
foundDecreases = foundDecreases || initialStops2.get(it.key()) < it.value() - EPSILON;
}
assertTrue(foundDecreases);
}
/**
* Test that increasing the walk speed on a walk-to-transit search
* a) decreases or leaves unchanged all access times.
* b) allows access to a superset of the originally accessible stops.
* c) decreases at least some access times.
*
* There was once a bug where bike speed was not correctly applied because we used the distance not the speed.
*/
@Test
public void testInitialStopWalkSpeedIncrease () throws Exception {
Graph g = buildGraphNoTransit();
addRegularStopGrid(g);
addTransitMultipleLines(g);
link(g);
g.index(new DefaultStreetVertexIndexFactory());
ProfileRequest req = new ProfileRequest();
req.fromLon = req.toLon = -83.0118;
req.fromLat = req.toLat = 39.9908;
req.date = new LocalDate(2015, 9, 17);
req.bikeSpeed = 4.1f;
req.walkSpeed = 1.3f;
req.fromTime = 7 * 3600;
req.toTime = 9 * 3600;
req.maxBikeTime = 20;
req.maxWalkTime = 20;
req.transitModes = new TraverseModeSet("TRANSIT");
req.accessModes = req.egressModes = req.directModes = new QualifiedModeSet("WALK");
RaptorWorkerData data = RepeatedRaptorProfileRouter.getRaptorWorkerData(req, g, null, new TaskStatistics());
assertNotNull(data);
RepeatedRaptorProfileRouter rrpr = new RepeatedRaptorProfileRouter(g, req);
TIntIntMap initialStops1 = rrpr.findInitialStops(false, data);
assertFalse(initialStops1.isEmpty());
// let's get crazy, set walk speed really high.
req.walkSpeed = 25f;
data = RepeatedRaptorProfileRouter.getRaptorWorkerData(req, g, null, new TaskStatistics());
assertNotNull(data);
rrpr = new RepeatedRaptorProfileRouter(g, req);
TIntIntMap initialStops2 = rrpr.findInitialStops(false, data);
// we should find decreases to at least some stops
boolean foundDecreases = false;
for (TIntIntIterator it = initialStops1.iterator(); it.hasNext();) {
it.advance();
// the reached stops from the faster search should be a superset of the reached stops from the slower search
assertTrue(initialStops2.containsKey(it.key()));
assertTrue("Found increase in travel time to stop", initialStops2.get(it.key()) <= it.value());
foundDecreases = foundDecreases || initialStops2.get(it.key()) < it.value() - EPSILON;
}
assertTrue("No decreases were found due to increased walk speed", foundDecreases);
}
}