public static int getPreviousArriveTime(
      RoutingRequest request, int arrivalTime, Vertex stopVertex) {

    int bestArrivalTime = -1;

    request.arriveBy = true;

    // find the alights
    for (Edge prealight : stopVertex.getIncoming()) {
      if (prealight instanceof PreAlightEdge) {
        Vertex arrival = prealight.getFromVertex(); // this is the arrival vertex
        for (Edge alight : arrival.getIncoming()) {
          if (alight instanceof TransitBoardAlight) {
            State state = new State(alight.getToVertex(), arrivalTime, request);
            State result = alight.traverse(state);
            if (result == null) continue;
            int time = (int) result.getTime();
            if (time > bestArrivalTime) {
              bestArrivalTime = time;
            }
          }
        }
      }
    }

    request.arriveBy = false;
    return bestArrivalTime;
  }
    /**
     * The safest bike lane should have a safety weight no lower than the time weight of a flat
     * street. This method divides the safety lengths by the length ratio of the safest street,
     * ensuring this property.
     *
     * @param graph
     */
    private void applyBikeSafetyFactor(Graph graph) {
      _log.info(
          GraphBuilderAnnotation.register(
              graph,
              Variety.GRAPHWIDE,
              "Multiplying all bike safety values by " + (1 / bestBikeSafety)));
      HashSet<Edge> seenEdges = new HashSet<Edge>();
      for (Vertex vertex : graph.getVertices()) {
        for (Edge e : vertex.getOutgoing()) {
          if (!(e instanceof PlainStreetEdge)) {
            continue;
          }
          PlainStreetEdge pse = (PlainStreetEdge) e;

          if (!seenEdges.contains(e)) {
            seenEdges.add(e);
            pse.setBicycleSafetyEffectiveLength(
                pse.getBicycleSafetyEffectiveLength() / bestBikeSafety);
          }
        }
        for (Edge e : vertex.getIncoming()) {
          if (!(e instanceof PlainStreetEdge)) {
            continue;
          }
          PlainStreetEdge pse = (PlainStreetEdge) e;

          if (!seenEdges.contains(e)) {
            seenEdges.add(e);
            pse.setBicycleSafetyEffectiveLength(
                pse.getBicycleSafetyEffectiveLength() / bestBikeSafety);
          }
        }
      }
    }
  public void testBoardAlightStopIndex() {
    Vertex stop_b_arrive = graph.getVertex("agency:C_arrive");
    Vertex stop_b_depart = graph.getVertex("agency:C_depart");

    Map<TripPattern, Integer> stopIndex = new HashMap<TripPattern, Integer>();
    for (Edge edge : stop_b_depart.getOutgoing()) {
      TransitBoardAlight tba = (TransitBoardAlight) edge;
      stopIndex.put(tba.getPattern(), tba.getStopIndex());
    }

    for (Edge edge : stop_b_arrive.getIncoming()) {
      TransitBoardAlight tba = (TransitBoardAlight) edge;
      if (stopIndex.containsKey(tba.getPattern()))
        assertEquals((Integer) stopIndex.get(tba.getPattern()), new Integer(tba.getStopIndex()));
    }
  }
示例#4
0
 /**
  * Internals of getRegionsForVertex; keeps track of seen vertices to avoid loops.
  *
  * @param regionData
  * @param vertex
  * @param seen
  * @param depth
  * @return
  */
 private static HashSet<Integer> getRegionsForVertex(
     RegionData regionData, Vertex vertex, HashSet<Vertex> seen, int depth) {
   seen.add(vertex);
   HashSet<Integer> regions = new HashSet<Integer>();
   int region = vertex.getGroupIndex();
   if (region >= 0) {
     regions.add(region);
   } else {
     for (Edge e : vertex.getOutgoing()) {
       final Vertex tov = e.getToVertex();
       if (!seen.contains(tov))
         regions.addAll(getRegionsForVertex(regionData, tov, seen, depth + 1));
     }
     for (Edge e : vertex.getIncoming()) {
       final Vertex fromv = e.getFromVertex();
       if (!seen.contains(fromv))
         regions.addAll(getRegionsForVertex(regionData, fromv, seen, depth + 1));
     }
   }
   return regions;
 }
  /**
   * Get edges connected to an vertex
   *
   * @return
   */
  @Secured({"ROLE_USER"})
  @GET
  @Path("/edgesForVertex")
  @Produces({MediaType.APPLICATION_JSON})
  public EdgesForVertex getEdgesForVertex(@QueryParam("vertex") String label) {

    Graph graph = graphService.getGraph();
    Vertex vertex = graph.getVertex(label);
    if (vertex == null) {
      return null;
    }
    EdgeSet incoming = new EdgeSet();
    incoming.addEdges(vertex.getIncoming(), graph);

    EdgeSet outgoing = new EdgeSet();
    outgoing.addEdges(vertex.getOutgoing(), graph);

    EdgesForVertex e4v = new EdgesForVertex();
    e4v.incoming = incoming.withGraph(graph);
    e4v.outgoing = outgoing.withGraph(graph);

    return e4v;
  }
  @Override
  public List<GraphPath> getPaths(RoutingRequest options) {

    if (options.rctx == null) {
      options.setRoutingContext(graphService.getGraph(options.getRouterId()));
      // move into setRoutingContext ?
      options.rctx.pathParsers =
          new PathParser[] {new BasicPathParser(), new NoThruTrafficPathParser()};
    }

    RemainingWeightHeuristic heuristic;
    if (options.getModes().isTransit()) {
      LOG.debug("Transit itinerary requested.");
      // always use the bidirectional heuristic because the others are not precise enough
      heuristic = new BidirectionalRemainingWeightHeuristic(options.rctx.graph);
    } else {
      LOG.debug("Non-transit itinerary requested.");
      heuristic = new DefaultRemainingWeightHeuristic();
    }

    // the states that will eventually be turned into paths and returned
    List<State> returnStates = new LinkedList<State>();

    BinHeap<State> pq = new BinHeap<State>();
    //        List<State> boundingStates = new ArrayList<State>();

    Vertex originVertex = options.rctx.origin;
    Vertex targetVertex = options.rctx.target;

    // increase maxWalk repeatedly in case hard limiting is in use
    WALK:
    for (double maxWalk = options.getMaxWalkDistance(); returnStates.isEmpty(); maxWalk *= 2) {
      if (maxWalk != Double.MAX_VALUE && maxWalk > MAX_WALK) {
        break;
      }
      LOG.debug("try search with max walk {}", maxWalk);
      // increase maxWalk if settings make trip impossible
      if (maxWalk
          < Math.min(
              distanceLibrary.distance(originVertex.getCoordinate(), targetVertex.getCoordinate()),
              originVertex.getDistanceToNearestTransitStop()
                  + targetVertex.getDistanceToNearestTransitStop())) continue WALK;
      options.setMaxWalkDistance(maxWalk);

      // cap search / heuristic weight
      final double AVG_TRANSIT_SPEED = 25; // m/sec
      double cutoff =
          (distanceLibrary.distance(originVertex.getCoordinate(), targetVertex.getCoordinate())
                  * 1.5)
              / AVG_TRANSIT_SPEED; // wait time is irrelevant in the heuristic
      cutoff += options.getMaxWalkDistance() * options.walkReluctance;
      options.maxWeight = cutoff;

      State origin = new State(options);
      // (used to) initialize heuristic outside loop so table can be reused
      heuristic.computeInitialWeight(origin, targetVertex);

      options.maxWeight = cutoff + 30 * 60 * options.waitReluctance;

      // reinitialize states for each retry
      HashMap<Vertex, List<State>> states = new HashMap<Vertex, List<State>>();
      pq.reset();
      pq.insert(origin, 0);
      long startTime = System.currentTimeMillis();
      long endTime = startTime + (int) (_timeouts[0] * 1000);
      LOG.debug("starttime {} endtime {}", startTime, endTime);
      QUEUE:
      while (!pq.empty()) {

        if (System.currentTimeMillis() > endTime) {
          LOG.debug("timeout at {} msec", System.currentTimeMillis() - startTime);
          if (returnStates.isEmpty()) break WALK; // disable walk distance increases
          else {
            storeMemory();
            break WALK;
          }
        }

        //                if (pq.peek_min_key() > options.maxWeight) {
        //                    LOG.debug("max weight {} exceeded", options.maxWeight);
        //                    break QUEUE;
        //                }

        State su = pq.extract_min();

        //                for (State bs : boundingStates) {
        //                    if (eDominates(bs, su)) {
        //                        continue QUEUE;
        //                    }
        //                }

        Vertex u = su.getVertex();

        if (traverseVisitor != null) {
          traverseVisitor.visitVertex(su);
        }

        if (u.equals(targetVertex)) {
          //                    boundingStates.add(su);
          returnStates.add(su);
          if (!options.getModes().isTransit()) break QUEUE;
          // options should contain max itineraries
          if (returnStates.size() >= _maxPaths) break QUEUE;
          if (returnStates.size() < _timeouts.length) {
            endTime = startTime + (int) (_timeouts[returnStates.size()] * 1000);
            LOG.debug(
                "{} path, set timeout to {}",
                returnStates.size(),
                _timeouts[returnStates.size()] * 1000);
          }
          continue QUEUE;
        }

        for (Edge e : options.isArriveBy() ? u.getIncoming() : u.getOutgoing()) {
          STATE:
          for (State new_sv = e.traverse(su); new_sv != null; new_sv = new_sv.getNextResult()) {
            if (traverseVisitor != null) {
              traverseVisitor.visitEdge(e, new_sv);
            }

            double h = heuristic.computeForwardWeight(new_sv, targetVertex);
            if (h == Double.MAX_VALUE) continue;
            //                    for (State bs : boundingStates) {
            //                        if (eDominates(bs, new_sv)) {
            //                            continue STATE;
            //                        }
            //                    }
            Vertex v = new_sv.getVertex();
            List<State> old_states = states.get(v);
            if (old_states == null) {
              old_states = new LinkedList<State>();
              states.put(v, old_states);
            } else {
              for (State old_sv : old_states) {
                if (eDominates(old_sv, new_sv)) {
                  continue STATE;
                }
              }
              Iterator<State> iter = old_states.iterator();
              while (iter.hasNext()) {
                State old_sv = iter.next();
                if (eDominates(new_sv, old_sv)) {
                  iter.remove();
                }
              }
            }
            if (traverseVisitor != null) traverseVisitor.visitEnqueue(new_sv);

            old_states.add(new_sv);
            pq.insert(new_sv, new_sv.getWeight() + h);
          }
        }
      }
    }
    storeMemory();

    // Make the states into paths and return them
    List<GraphPath> paths = new LinkedList<GraphPath>();
    for (State s : returnStates) {
      LOG.debug(s.toStringVerbose());
      paths.add(new GraphPath(s, true));
    }
    // sort by arrival time, though paths are already in order of increasing difficulty
    // Collections.sort(paths, new PathComparator(origin.getOptions().isArriveBy()));
    return paths;
  }