public double getTargetDistance(Vertex vertex) { int vertexIndex = vertex.getIndex(); if (vertexIndex < distance.length) { if (distance[vertexIndex] > 0.0) { return distance[vertexIndex]; } else { double d = distanceLibrary.fastDistance( realTargetCoordinate.y, realTargetCoordinate.x, vertex.getY(), vertex.getX()); distance[vertexIndex] = d; return d; } } else { return distanceLibrary.fastDistance( realTargetCoordinate.y, realTargetCoordinate.x, vertex.getY(), vertex.getX()); } }
/** * Computes the angle from the first point to the last point of a LineString or MultiLineString. * TODO: put this method into org.opentripplanner.common.geometry.DirectionUtils * * @param geometry a LineString or a MultiLineString * @return */ public synchronized double getFirstToLastSegmentAngle(Geometry geometry) { LineString line; if (geometry instanceof MultiLineString) { line = (LineString) geometry.getGeometryN(geometry.getNumGeometries() - 1); } else { assert geometry instanceof LineString; line = (LineString) geometry; } int numPoints = line.getNumPoints(); Coordinate coord0 = line.getCoordinateN(0); Coordinate coord1 = line.getCoordinateN(numPoints - 1); int i = numPoints - 3; while (distanceLibrary.fastDistance(coord0, coord1) < 10 && i >= 0) { coord1 = line.getCoordinateN(i--); } geodeticCalculator.setStartingGeographicPoint(coord0.x, coord0.y); geodeticCalculator.setDestinationGeographicPoint(coord1.x, coord1.y); return geodeticCalculator.getAzimuth() * Math.PI / 180; }
@Override public boolean shouldSkipTraversalResult( Vertex origin, Vertex target, State parent, State current, ShortestPathTree spt, RoutingRequest traverseOptions) { if (realTarget == null) return false; final Vertex vertex = current.getVertex(); int vertexIndex = vertex.getIndex(); if (vertexIndex < distance.length) { if (distance[vertexIndex] > 0.0) { targetDistance = distance[vertexIndex]; } else { targetDistance = distanceLibrary.fastDistance( realTargetCoordinate.y, realTargetCoordinate.x, vertex.getY(), vertex.getX()); distance[vertexIndex] = targetDistance; if (vertex instanceof TransitStop && targetDistance < bestTargetDistance) { bestTargetDistance = targetDistance; } } } else { targetDistance = distanceLibrary.fastDistance( realTargetCoordinate.y, realTargetCoordinate.x, vertex.getY(), vertex.getX()); } final double remainingWalk = traverseOptions.maxWalkDistance - current.getWalkDistance(); final double minWalk; double minTime = 0; if (targetDistance > remainingWalk) { // then we must have some transit + some walk. minWalk = this.distanceToNearestTransitStop + vertex.getDistanceToNearestTransitStop(); minTime = options.isArriveBy() ? traverseOptions.getAlightSlack() : traverseOptions.getBoardSlack(); if (current.getBackEdge() instanceof StreetEdge && transitLocalStreets != null && !transitLocalStreets.transferrable(vertex)) { return true; } } else { // could walk directly to destination if (targetDistance < distanceToNearestTransitStop || transitLocalStreets == null || !transitLocalStreets.transferrable(vertex)) minWalk = targetDistance; else minWalk = distanceToNearestTransitStop; } if (minWalk > remainingWalk) return true; final double optimisticDistance = current.getWalkDistance() + minWalk; final double walkTime = minWalk / speedUpperBound; minTime += (targetDistance - minWalk) / Raptor.MAX_TRANSIT_SPEED + walkTime; double stateTime = current.getOptimizedElapsedTime() + minTime; double walkDistance = FastMath.max( optimisticDistance * Raptor.WALK_EPSILON, optimisticDistance + transferTimeInWalkDistance); int i = 0; boolean prevBounded = !bounders.isEmpty(); for (State bounder : bounders) { if (removedBoundingStates.contains(bounder)) continue; if (current.getWeight() + minTime + walkTime * (options.getWalkReluctance() - 1) > bounder.getWeight() * WORST_WEIGHT_DIFFERENCE_FACTOR) { return true; } int prevTime = previousArrivalTime.get(i++); if (walkDistance > bounder.getWalkDistance() && current.getNumBoardings() >= bounder.getNumBoardings()) { if (current.getElapsedTime() + minTime >= bounder.getElapsedTime()) { return true; } else if (prevTime > 0 && (options.arriveBy ? (current.getTime() - minTime >= prevTime) : ((current.getTime() + minTime) <= prevTime))) { prevBounded = false; } } else { prevBounded = false; } // check that the new path is not much longer in time than the bounding path if (bounder.getOptimizedElapsedTime() * timeBoundFactor < stateTime) { return true; } } return prevBounded; }