Search in sources :

Example 36 with TraverseModeSet

use of org.opentripplanner.routing.core.TraverseModeSet in project OpenTripPlanner by opentripplanner.

the class ConvertToFrequencyTest method testSimpleConversion.

/**
 * The simplest case of frequency conversion: no weird loop routes or anything like that, travel times always same, etc.
 */
@Test
public void testSimpleConversion() throws Exception {
    Graph gg = buildGraphNoTransit();
    addTransit(gg);
    link(gg);
    gg.index(new DefaultStreetVertexIndexFactory());
    ProfileRequest pr1 = new ProfileRequest();
    pr1.date = new LocalDate(2015, 6, 10);
    pr1.fromTime = 7 * 3600;
    pr1.toTime = 9 * 3600;
    pr1.fromLat = pr1.toLat = 39.9621;
    pr1.fromLon = pr1.toLon = -83.0007;
    pr1.accessModes = pr1.egressModes = pr1.directModes = new QualifiedModeSet("WALK");
    pr1.transitModes = new TraverseModeSet("TRANSIT");
    RepeatedRaptorProfileRouter rrpr1 = new RepeatedRaptorProfileRouter(gg, pr1);
    rrpr1.route();
    ProfileRequest pr2 = new ProfileRequest();
    pr2.date = new LocalDate(2015, 6, 10);
    pr2.fromTime = 7 * 3600;
    pr2.toTime = 9 * 3600;
    pr2.fromLat = pr2.toLat = 39.9621;
    pr2.fromLon = pr2.toLon = -83.0007;
    pr2.accessModes = pr2.egressModes = pr2.directModes = new QualifiedModeSet("WALK");
    pr2.transitModes = new TraverseModeSet("TRANSIT");
    ConvertToFrequency ctf = new ConvertToFrequency();
    ctf.groupBy = ConvertToFrequency.ConversionGroup.ROUTE_DIRECTION;
    ctf.routeId = new String[] { "route" };
    ctf.windowStart = 5 * 3600;
    ctf.windowEnd = 10 * 3600;
    pr2.scenario = new Scenario(0);
    pr2.scenario.modifications = Arrays.asList(ctf);
    RepeatedRaptorProfileRouter rrpr2 = new RepeatedRaptorProfileRouter(gg, pr2);
    rrpr2.route();
    assertFalse(rrpr1.raptorWorkerData.hasFrequencies);
    assertTrue(rrpr2.raptorWorkerData.hasFrequencies);
    RaptorWorkerTimetable tt = rrpr2.raptorWorkerData.timetablesForPattern.get(0);
    assertEquals(FakeGraph.FREQUENCY, tt.headwaySecs[0]);
    assertEquals(FakeGraph.TRAVEL_TIME, tt.frequencyTrips[0][2]);
}
Also used : RepeatedRaptorProfileRouter(org.opentripplanner.profile.RepeatedRaptorProfileRouter) FakeGraph(org.opentripplanner.graph_builder.module.FakeGraph) Graph(org.opentripplanner.routing.graph.Graph) ConvertToFrequency(org.opentripplanner.analyst.scenario.ConvertToFrequency) QualifiedModeSet(org.opentripplanner.api.parameter.QualifiedModeSet) TraverseModeSet(org.opentripplanner.routing.core.TraverseModeSet) DefaultStreetVertexIndexFactory(org.opentripplanner.routing.impl.DefaultStreetVertexIndexFactory) RaptorWorkerTimetable(org.opentripplanner.profile.RaptorWorkerTimetable) ProfileRequest(org.opentripplanner.profile.ProfileRequest) LocalDate(org.joda.time.LocalDate) Scenario(org.opentripplanner.analyst.scenario.Scenario) Test(org.junit.Test)

Example 37 with TraverseModeSet

use of org.opentripplanner.routing.core.TraverseModeSet in project OpenTripPlanner by opentripplanner.

the class ConvertToFrequencyTest method testMultiplePatterns.

/**
 * Test the case where there are multiple patterns that need to be chosen from.
 */
@Test
public void testMultiplePatterns() throws Exception {
    Graph gg = buildGraphNoTransit();
    addMultiplePatterns(gg);
    link(gg);
    gg.index(new DefaultStreetVertexIndexFactory());
    ProfileRequest pr1 = new ProfileRequest();
    pr1.date = new LocalDate(2015, 6, 10);
    pr1.fromTime = 7 * 3600;
    pr1.toTime = 9 * 3600;
    pr1.fromLat = pr1.toLat = 39.9621;
    pr1.fromLon = pr1.toLon = -83.0007;
    pr1.accessModes = pr1.egressModes = pr1.directModes = new QualifiedModeSet("WALK");
    pr1.transitModes = new TraverseModeSet("TRANSIT");
    RepeatedRaptorProfileRouter rrpr1 = new RepeatedRaptorProfileRouter(gg, pr1);
    rrpr1.route();
    ProfileRequest pr2 = new ProfileRequest();
    pr2.date = new LocalDate(2015, 6, 10);
    pr2.fromTime = 7 * 3600;
    pr2.toTime = 9 * 3600;
    pr2.fromLat = pr2.toLat = 39.9621;
    pr2.fromLon = pr2.toLon = -83.0007;
    pr2.accessModes = pr2.egressModes = pr2.directModes = new QualifiedModeSet("WALK");
    pr2.transitModes = new TraverseModeSet("TRANSIT");
    ConvertToFrequency ctf = new ConvertToFrequency();
    ctf.groupBy = ConvertToFrequency.ConversionGroup.ROUTE_DIRECTION;
    ctf.routeId = new String[] { "route" };
    ctf.windowStart = 5 * 3600;
    ctf.windowEnd = 10 * 3600;
    pr2.scenario = new Scenario(0);
    pr2.scenario.modifications = Arrays.asList(ctf);
    RepeatedRaptorProfileRouter rrpr2 = new RepeatedRaptorProfileRouter(gg, pr2);
    rrpr2.route();
    assertFalse(rrpr1.raptorWorkerData.hasFrequencies);
    assertTrue(rrpr2.raptorWorkerData.hasFrequencies);
    // everything should have gotten merged into one pattern
    assertEquals(1, rrpr2.raptorWorkerData.timetablesForPattern.size());
    RaptorWorkerTimetable tt = rrpr2.raptorWorkerData.timetablesForPattern.get(0);
    // should be no frequency variation because trips on all patterns are considered for frequencies.
    // there should be no travel time variation because only trips on the dominant pattern are considered
    // for travel time.
    assertEquals(FakeGraph.FREQUENCY, tt.headwaySecs[0]);
    assertEquals(FakeGraph.TRAVEL_TIME, tt.frequencyTrips[0][2]);
    // now try it with groupings by pattern
    ConvertToFrequency ctf3 = new ConvertToFrequency();
    ctf3.groupBy = ConvertToFrequency.ConversionGroup.PATTERN;
    ctf3.routeId = new String[] { "route" };
    ctf3.windowStart = 5 * 3600;
    ctf3.windowEnd = 10 * 3600;
    ProfileRequest pr3 = new ProfileRequest();
    pr3.date = new LocalDate(2015, 6, 10);
    pr3.fromTime = 7 * 3600;
    pr3.toTime = 9 * 3600;
    pr3.fromLat = pr2.toLat = 39.9621;
    pr3.fromLon = pr2.toLon = -83.0007;
    pr3.accessModes = pr2.egressModes = pr2.directModes = new QualifiedModeSet("WALK");
    pr3.transitModes = new TraverseModeSet("TRANSIT");
    pr3.scenario = new Scenario(0);
    pr3.scenario.modifications = Arrays.asList(ctf3);
    RepeatedRaptorProfileRouter rrpr3 = new RepeatedRaptorProfileRouter(gg, pr3);
    rrpr3.route();
    assertTrue(rrpr3.raptorWorkerData.hasFrequencies);
    // should be converted to two independent patterns
    assertEquals(2, rrpr3.raptorWorkerData.timetablesForPattern.size());
    RaptorWorkerTimetable shrt, lng;
    if (rrpr3.raptorWorkerData.timetablesForPattern.get(0).nStops == 2) {
        shrt = rrpr3.raptorWorkerData.timetablesForPattern.get(0);
        lng = rrpr3.raptorWorkerData.timetablesForPattern.get(1);
    } else {
        lng = rrpr3.raptorWorkerData.timetablesForPattern.get(0);
        shrt = rrpr3.raptorWorkerData.timetablesForPattern.get(1);
    }
    assertEquals(3, lng.nStops);
    assertEquals(2, shrt.nStops);
    assertEquals(675, lng.headwaySecs[0]);
    assertEquals((int) (FakeGraph.FREQUENCY / 0.1), shrt.headwaySecs[0]);
    // make sure that the hop time is always FakeGraph.TRAVEL_TIME
    assertEquals(FakeGraph.TRAVEL_TIME, shrt.frequencyTrips[0][2]);
    assertEquals(FakeGraph.TRAVEL_TIME, lng.frequencyTrips[0][2]);
    assertEquals(FakeGraph.TRAVEL_TIME * 2, lng.frequencyTrips[0][4]);
}
Also used : RepeatedRaptorProfileRouter(org.opentripplanner.profile.RepeatedRaptorProfileRouter) FakeGraph(org.opentripplanner.graph_builder.module.FakeGraph) Graph(org.opentripplanner.routing.graph.Graph) ConvertToFrequency(org.opentripplanner.analyst.scenario.ConvertToFrequency) QualifiedModeSet(org.opentripplanner.api.parameter.QualifiedModeSet) TraverseModeSet(org.opentripplanner.routing.core.TraverseModeSet) DefaultStreetVertexIndexFactory(org.opentripplanner.routing.impl.DefaultStreetVertexIndexFactory) RaptorWorkerTimetable(org.opentripplanner.profile.RaptorWorkerTimetable) ProfileRequest(org.opentripplanner.profile.ProfileRequest) LocalDate(org.joda.time.LocalDate) Scenario(org.opentripplanner.analyst.scenario.Scenario) Test(org.junit.Test)

Example 38 with TraverseModeSet

use of org.opentripplanner.routing.core.TraverseModeSet in project OpenTripPlanner by opentripplanner.

the class RepeatedRaptorComparison method main.

public static void main(String... args) {
    if (args.length == 0) {
        System.err.println("too few arguments.");
        return;
    }
    // build a graph
    File graphDir = new File(args[0]);
    Graph graph = buildGraph(graphDir);
    DB comparisonDb = null;
    BTreeMap<Fun.Tuple3<String, String, ResultEnvelope.Which>, Integer> comparison = null;
    // open the comparison file, if we have one.
    if (args.length > 1) {
        comparisonDb = DBMaker.newFileDB(new File(args[1])).readOnly().transactionDisable().closeOnJvmShutdown().cacheSize(24).asyncWriteEnable().make();
        comparison = comparisonDb.getTreeMap("results");
    }
    String outputName = args.length > 2 ? args[2] : MavenVersion.VERSION.commit + ".db";
    DB outputDb = DBMaker.newFileDB(new File(outputName)).transactionDisable().cacheSize(48).closeOnJvmShutdown().make();
    final BTreeMap<Fun.Tuple3<String, String, ResultEnvelope.Which>, Integer> output = outputDb.createTreeMap("results").valueSerializer(Serializer.JAVA).makeOrGet();
    // if we have a comparison file, get the pointset from it. Otherwise choose some randomly.
    Collection<String> vertexLabels;
    PointSet pset;
    if (comparison != null) {
        // clooge, pointset is stored in its own map in db.
        pset = comparisonDb.<String, PointSet>getTreeMap("pointset").get("pointset");
    } else {
        // choose some vertices
        List<Vertex> vertices = graph.getVertices().stream().filter(v -> v.getLabel().startsWith("osm:node:")).limit(1000).collect(Collectors.toList());
        // make a pointset
        pset = new PointSet(vertices.size());
        int featIdx = 0;
        for (Vertex v : vertices) {
            PointFeature pf = new PointFeature();
            pf.setId(v.getLabel());
            pf.setLat(v.getLat() + OFFSET_Y);
            pf.setLon(v.getLon() + OFFSET_X);
            pset.addFeature(pf, featIdx++);
        }
        outputDb.createTreeMap("pointset").<String, PointSet>make().put("pointset", pset);
    }
    SampleSet ss = new SampleSet(pset, graph.getSampleFactory());
    final BTreeMap<Fun.Tuple3<String, String, ResultEnvelope.Which>, Integer> comparisonResults = comparison;
    Histogram bestCaseHisto = new Histogram("Best case");
    Histogram avgCaseHisto = new Histogram("Average");
    Histogram worstCaseHisto = new Histogram("Worst case");
    ProfileRequest template = new ProfileRequest();
    template.accessModes = new QualifiedModeSet("WALK");
    template.analyst = true;
    template.maxWalkTime = 20 * 60;
    template.walkSpeed = 1.3f;
    template.fromTime = 7 * 3600;
    template.toTime = 9 * 3600;
    template.date = new LocalDate(2015, 8, 4);
    RaptorWorkerData data = RepeatedRaptorProfileRouter.getRaptorWorkerData(template, graph, ss, new TaskStatistics());
    // do the computation and comparison
    IntStream.range(0, pset.featureCount()).parallel().forEach(idx -> {
        if (idx % 100 == 0)
            System.out.println(idx + " points complete");
        Coordinate coord = pset.getCoordinate(idx);
        String origin = pset.getFeature(idx).getId();
        ProfileRequest req;
        try {
            req = template.clone();
        } catch (CloneNotSupportedException e) {
            /* can't happen */
            throw new RuntimeException(e);
        }
        req.maxWalkTime = 20 * 60;
        req.fromLat = req.toLat = coord.y;
        req.fromLon = req.toLon = coord.x;
        // 7 to 9 AM
        req.fromTime = 7 * 3600;
        req.toTime = 9 * 3600;
        req.transitModes = new TraverseModeSet("TRANSIT");
        RepeatedRaptorProfileRouter rrpr = new RepeatedRaptorProfileRouter(graph, req, ss);
        rrpr.raptorWorkerData = data;
        rrpr.includeTimes = true;
        // TODO we really want to disable both isochrone and accessibility generation here.
        // Because a sampleSet is provided it's going to make accessibility information (not isochrones).
        ResultEnvelope results = new ResultEnvelope();
        try {
            results = rrpr.route();
        } catch (Exception e) {
            LOG.error("Exception during routing", e);
            return;
        }
        for (ResultEnvelope.Which which : new ResultEnvelope.Which[] { ResultEnvelope.Which.BEST_CASE, ResultEnvelope.Which.AVERAGE, ResultEnvelope.Which.WORST_CASE }) {
            Histogram histogram;
            ResultSet resultSet;
            switch(which) {
                case BEST_CASE:
                    histogram = bestCaseHisto;
                    resultSet = results.bestCase;
                    break;
                case WORST_CASE:
                    histogram = worstCaseHisto;
                    resultSet = results.worstCase;
                    break;
                case AVERAGE:
                    histogram = avgCaseHisto;
                    resultSet = results.avgCase;
                    break;
                default:
                    histogram = null;
                    resultSet = null;
            }
            // comparison.
            for (int i = 0; i < resultSet.times.length; i++) {
                int time = resultSet.times[i];
                // TODO this is creating a PointFeature obj to hold the id at each call
                // Cache?
                String dest = pset.getFeature(i).getId();
                Fun.Tuple3<String, String, ResultEnvelope.Which> key = new Fun.Tuple3<>(origin, dest, which);
                output.put(key, time);
                if (time < 0) {
                    LOG.error("Path from {}  to {} has negative time {}", origin, dest, time);
                }
                if (comparisonResults != null) {
                    int time0 = comparisonResults.get(key);
                    int deltaMinutes;
                    if (time0 == RaptorWorker.UNREACHED && time != RaptorWorker.UNREACHED)
                        deltaMinutes = (time / 60) - 120;
                    else if (time == RaptorWorker.UNREACHED && time0 != RaptorWorker.UNREACHED)
                        deltaMinutes = 120 - (time0 / 60);
                    else
                        deltaMinutes = (time - time0) / 60;
                    // histograms are not threadsafe
                    synchronized (histogram) {
                        histogram.add(deltaMinutes);
                    }
                }
            }
        }
    });
    output.close();
    if (comparisonDb != null) {
        comparisonDb.close();
        bestCaseHisto.displayHorizontal();
        System.out.println("mean: " + bestCaseHisto.mean());
        avgCaseHisto.displayHorizontal();
        System.out.println("mean: " + avgCaseHisto.mean());
        worstCaseHisto.displayHorizontal();
        System.out.println("mean: " + worstCaseHisto.mean());
    }
}
Also used : Vertex(org.opentripplanner.routing.graph.Vertex) Histogram(org.opentripplanner.common.Histogram) QualifiedModeSet(org.opentripplanner.api.parameter.QualifiedModeSet) LocalDate(org.joda.time.LocalDate) RepeatedRaptorProfileRouter(org.opentripplanner.profile.RepeatedRaptorProfileRouter) TaskStatistics(org.opentripplanner.analyst.cluster.TaskStatistics) RaptorWorkerData(org.opentripplanner.profile.RaptorWorkerData) ResultEnvelope(org.opentripplanner.analyst.cluster.ResultEnvelope) TraverseModeSet(org.opentripplanner.routing.core.TraverseModeSet) ProfileRequest(org.opentripplanner.profile.ProfileRequest) Graph(org.opentripplanner.routing.graph.Graph) Coordinate(com.vividsolutions.jts.geom.Coordinate) File(java.io.File)

Example 39 with TraverseModeSet

use of org.opentripplanner.routing.core.TraverseModeSet in project OpenTripPlanner by opentripplanner.

the class ProfileRouter method findClosestStops.

/**
 * 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 QualifiedMode qmode, boolean dest) {
    // Make a normal OTP routing request so we can traverse edges and use GenericAStar
    // TODO make a function that builds normal routing requests from profile requests
    RoutingRequest rr = new RoutingRequest(new TraverseModeSet());
    qmode.applyToRoutingRequest(rr, request.transitModes.isTransit());
    rr.from = (new GenericLocation(request.fromLat, request.fromLon));
    // FIXME requires destination to be set, not necessary for analyst
    rr.to = new GenericLocation(request.toLat, request.toLon);
    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.dominanceFunction = new DominanceFunction.EarliestArrival();
    // RR dateTime defaults to currentTime.
    // If elapsed time is not capped, searches are very slow.
    int minAccessTime = 0;
    int maxAccessTime = request.maxWalkTime;
    if (qmode.mode == TraverseMode.BICYCLE) {
        rr.bikeSpeed = request.bikeSpeed;
        minAccessTime = request.minBikeTime;
        maxAccessTime = request.maxBikeTime;
        rr.optimize = OptimizeType.TRIANGLE;
        rr.setTriangleNormalized(request.bikeSafe, request.bikeSlope, request.bikeTime);
    } else if (qmode.mode == TraverseMode.CAR) {
        rr.carSpeed = request.carSpeed;
        minAccessTime = request.minCarTime;
        maxAccessTime = request.maxCarTime;
    }
    // convert from minutes to seconds
    long worstElapsedTimeSeconds = maxAccessTime * 60;
    if (dest)
        worstElapsedTimeSeconds *= -1;
    rr.worstTime = (rr.dateTime + worstElapsedTimeSeconds);
    AStar astar = new AStar();
    rr.setNumItineraries(1);
    StopFinderTraverseVisitor visitor = new StopFinderTraverseVisitor(qmode, minAccessTime * 60);
    astar.setTraverseVisitor(visitor);
    // timeout in seconds
    astar.getShortestPathTree(rr, 5);
    // Save the routing context for later cleanup. We need its temporary edges to render street segments at the end.
    routingContexts.add(rr.rctx);
    return visitor.stopClustersFound.values();
}
Also used : AStar(org.opentripplanner.routing.algorithm.AStar) GenericLocation(org.opentripplanner.common.model.GenericLocation) RoutingRequest(org.opentripplanner.routing.core.RoutingRequest) TraverseModeSet(org.opentripplanner.routing.core.TraverseModeSet) DominanceFunction(org.opentripplanner.routing.spt.DominanceFunction)

Example 40 with TraverseModeSet

use of org.opentripplanner.routing.core.TraverseModeSet in project OpenTripPlanner by opentripplanner.

the class ProfileRouter method findDirectOption.

/**
 * Look for an option connecting origin to destination without using transit.
 */
private void findDirectOption(QualifiedMode qmode) {
    // Make a normal OTP routing request so we can traverse edges and use GenericAStar
    RoutingRequest rr = new RoutingRequest(new TraverseModeSet());
    // false because we never use transit in direct options
    qmode.applyToRoutingRequest(rr, false);
    if (qmode.mode == TraverseMode.BICYCLE) {
        // TRIANGLE should only affect bicycle searches, but we wrap this in a conditional just to be clear.
        rr.optimize = OptimizeType.TRIANGLE;
        rr.setTriangleNormalized(request.bikeSafe, request.bikeSlope, request.bikeTime);
    }
    rr.from = (new GenericLocation(request.fromLat, request.fromLon));
    rr.to = new GenericLocation(request.toLat, request.toLon);
    rr.setArriveBy(false);
    rr.setRoutingContext(graph);
    rr.dominanceFunction = new DominanceFunction.MinimumWeight();
    // This is not a batch search, it is a point-to-point search with goal direction.
    // Impose a max time to protect against very slow searches.
    int worstElapsedTime = request.streetTime * 60;
    rr.worstTime = (rr.dateTime + worstElapsedTime);
    rr.walkSpeed = request.walkSpeed;
    rr.bikeSpeed = request.bikeSpeed;
    AStar astar = new AStar();
    rr.setNumItineraries(1);
    ShortestPathTree spt = astar.getShortestPathTree(rr, 5);
    State state = spt.getState(rr.rctx.target);
    if (state != null) {
        LOG.info("Found non-transit option for {}", qmode);
        directPaths.add(new StopAtDistance(state, qmode));
    }
    // save context for later cleanup so temp edges remain available
    routingContexts.add(rr.rctx);
}
Also used : ShortestPathTree(org.opentripplanner.routing.spt.ShortestPathTree) State(org.opentripplanner.routing.core.State) AStar(org.opentripplanner.routing.algorithm.AStar) GenericLocation(org.opentripplanner.common.model.GenericLocation) RoutingRequest(org.opentripplanner.routing.core.RoutingRequest) TraverseModeSet(org.opentripplanner.routing.core.TraverseModeSet) DominanceFunction(org.opentripplanner.routing.spt.DominanceFunction)

Aggregations

TraverseModeSet (org.opentripplanner.routing.core.TraverseModeSet)44 Test (org.junit.Test)25 RoutingRequest (org.opentripplanner.routing.core.RoutingRequest)17 Graph (org.opentripplanner.routing.graph.Graph)14 Edge (org.opentripplanner.routing.graph.Edge)10 Vertex (org.opentripplanner.routing.graph.Vertex)10 Coordinate (com.vividsolutions.jts.geom.Coordinate)8 QualifiedModeSet (org.opentripplanner.api.parameter.QualifiedModeSet)8 GenericLocation (org.opentripplanner.common.model.GenericLocation)8 ShortestPathTree (org.opentripplanner.routing.spt.ShortestPathTree)8 LocalDate (org.joda.time.LocalDate)7 ProfileRequest (org.opentripplanner.profile.ProfileRequest)7 RepeatedRaptorProfileRouter (org.opentripplanner.profile.RepeatedRaptorProfileRouter)7 StreetEdge (org.opentripplanner.routing.edgetype.StreetEdge)6 GraphPath (org.opentripplanner.routing.spt.GraphPath)6 FakeGraph (org.opentripplanner.graph_builder.module.FakeGraph)5 DefaultStreetVertexIndexFactory (org.opentripplanner.routing.impl.DefaultStreetVertexIndexFactory)5 NonLocalizedString (org.opentripplanner.util.NonLocalizedString)5 LineString (com.vividsolutions.jts.geom.LineString)4 ArrayList (java.util.ArrayList)4