/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.opentripplanner.graph_builder.impl.transit_local_streets; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import org.opentripplanner.common.model.T2; import org.opentripplanner.graph_builder.services.GraphBuilder; import org.opentripplanner.routing.algorithm.GenericDijkstra; import org.opentripplanner.routing.algorithm.strategies.TransitLocalStreetService; import org.opentripplanner.routing.core.OptimizeType; 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.impl.raptor.MaxWalkState; import org.opentripplanner.routing.spt.ShortestPathTree; import org.opentripplanner.routing.vertextype.TransitStop; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TransitLocalStreetComputer implements GraphBuilder { private static Logger log = LoggerFactory.getLogger(TransitLocalStreetComputer.class); private boolean saveShortestPaths = false; @Override public void buildGraph(Graph graph, HashMap<Class<?>, Object> extra) { HashSet<Vertex> transitShortestPathVertices = new HashSet<Vertex>(); // This is necessary for storing walk distances by vertex index graph.rebuildVertexAndEdgeIndices(); RoutingRequest walk = new RoutingRequest(TraverseMode.WALK); RoutingRequest wheelchair = new RoutingRequest(TraverseMode.WALK); wheelchair.wheelchairAccessible = true; RoutingRequest bikeflat = new RoutingRequest(TraverseMode.BICYCLE); bikeflat.optimize = OptimizeType.FLAT; RoutingRequest bikesafe = new RoutingRequest(TraverseMode.BICYCLE); bikesafe.optimize = OptimizeType.SAFE; RoutingRequest bikequick = new RoutingRequest(TraverseMode.BICYCLE); bikequick.optimize = OptimizeType.QUICK; RoutingRequest[] requests = new RoutingRequest[] { walk, wheelchair, bikeflat, bikesafe, bikequick }; int i = 0; final Collection<Vertex> allVertices = graph.getVertices(); HashMap<Vertex, HashMap<Vertex, int[]>> paths = new HashMap<Vertex, HashMap<Vertex, int[]>>(); HashMap<Vertex, HashMap<Vertex, T2<Double, Integer>>> costs = new HashMap<Vertex, HashMap<Vertex, T2<Double, Integer>>>(); for (Vertex v : allVertices) { ++i; if (i % 1000 == 0) { log.debug(i + " / " + allVertices.size()); } if (!(v instanceof TransitStop)) { continue; } // find SPT from this transit stop according to various modes; get all transit // stops in spt; get path to said stops; mark vertices for (RoutingRequest req : requests) { req.setRoutingContext(graph, v, null); req.setMaxWalkDistance(3000); GenericDijkstra dijkstra = new GenericDijkstra(req); State origin = new MaxWalkState(v, req); ShortestPathTree spt = dijkstra.getShortestPathTree(origin); HashMap<Vertex, int[]> map = null; HashMap<Vertex, T2<Double, Integer>> cost = null; if (req == walk && saveShortestPaths ) { map = new HashMap<Vertex, int[]>(); cost = new HashMap<Vertex, T2<Double, Integer>>(); paths.put(v, map); costs.put(v, cost); } int[] path = new int[1000]; for (State s : spt.getAllStates()) { Vertex destStopVertex = s.getVertex(); if (destStopVertex instanceof TransitStop) { int pathIndex = 0; if (req == walk && saveShortestPaths ) { cost.put(destStopVertex, new T2<Double, Integer>(s.getWalkDistance(), (int) s.getElapsedTimeSeconds())); } while (s != null) { transitShortestPathVertices.add(s.getVertex()); path[pathIndex++] = s.getVertex().getIndex(); s = s.getBackState(); } if (req == walk && saveShortestPaths ) { map.put(destStopVertex, Arrays.copyOf(path, pathIndex)); } } } } } TransitLocalStreetService service = new TransitLocalStreetService( transitShortestPathVertices, paths, costs); graph.putService(TransitLocalStreetService.class, service); } @Override public List<String> provides() { return Arrays.asList("transit_local_streets"); } @Override public List<String> getPrerequisites() { return Arrays.asList("streets", "transit", "linking"); } @Override public void checkInputs() { // nothing to do } }