Skip to content

Commit

Permalink
VGF-67 call-n-ride can go to other transit stops
Browse files Browse the repository at this point in the history
  • Loading branch information
sdjacobs committed Aug 25, 2017
1 parent 264ac13 commit 552017c
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 7 deletions.
Expand Up @@ -448,6 +448,8 @@ public class RoutingRequest implements Cloneable, Serializable {
/** Whether to apply the ellipsoid->geoid offset to all elevations in the response */
public boolean geoidElevation = false;

public boolean enterStationsWithCar = false;

/** Saves split edge which can be split on origin/destination search
*
* This is used so that TrivialPathException is thrown if origin and destination search would split the same edge
Expand Down
Expand Up @@ -114,7 +114,7 @@ public State traverse(State s0) {

/* Only enter stations in CAR mode if parking is not required (kiss and ride) */
/* Note that in arriveBy searches this is double-traversing link edges to fork the state into both WALK and CAR mode. This is an insane hack. */
if (s0.getNonTransitMode() == TraverseMode.CAR) {
if (s0.getNonTransitMode() == TraverseMode.CAR && !req.enterStationsWithCar) {
if (req.kissAndRide && !s0.isCarParked()) {
s1.setCarParked(true);
} else {
Expand Down
Expand Up @@ -13,6 +13,8 @@ the License, or (props, at your option) any later version.

package org.opentripplanner.routing.flex;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.linearref.LengthIndexedLine;
Expand All @@ -25,6 +27,7 @@ the License, or (props, at your option) any later version.
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.core.TraverseMode;
import org.opentripplanner.routing.edgetype.PatternHop;
import org.opentripplanner.routing.edgetype.TripPattern;
import org.opentripplanner.routing.edgetype.flex.TemporaryPartialPatternHop;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.graph.Vertex;
Expand All @@ -33,16 +36,25 @@ the License, or (props, at your option) any later version.
import org.opentripplanner.routing.vertextype.PatternDepartVertex;
import org.opentripplanner.routing.vertextype.PatternStopVertex;
import org.opentripplanner.routing.vertextype.StreetVertex;
import org.opentripplanner.routing.vertextype.TemporaryVertex;
import org.opentripplanner.routing.vertextype.TransitStop;
import org.opentripplanner.routing.vertextype.flex.TemporaryTransitStop;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
* Add temporary vertices/edges for deviated-route service.
*/
public class DeviatedRouteGraphModifier extends GtfsFlexGraphModifier {

private static final int MAX_DRS_SEARCH_DIST = 1600 * 10; // approx 5 mile limit. Could be set by data.

// want to ensure we only keep one pattern hop per trip pattern
private Map<TripPattern, PatternHop> directServices = Maps.newHashMap();
private Set<State> transitStopStates = Sets.newHashSet();

public DeviatedRouteGraphModifier(Graph graph) {
super(graph);
}
Expand Down Expand Up @@ -129,15 +141,58 @@ private boolean tooLittleOnRoute(PatternHop originalHop, LengthIndexedLine line,
@Override
public boolean checkHopAllowsBoardAlight(State s, PatternHop hop, boolean boarding) {
StreetVertex sv = findFirstStreetVertex(s);
Point orig = GeometryUtils.getGeometryFactory().createPoint(sv.getCoordinate());
Point dest = GeometryUtils.getGeometryFactory().createPoint(s.getVertex().getCoordinate());
boolean ret = false;
if (hop.hasServiceArea()) {
Point orig = GeometryUtils.getGeometryFactory().createPoint(sv.getCoordinate());
Point dest = GeometryUtils.getGeometryFactory().createPoint(s.getVertex().getCoordinate());
if (hop.getServiceArea().contains(orig) && hop.getServiceArea().contains(dest)) {
return true;
ret = true;
}
}
if (!ret && hop.getServiceAreaRadius() > 0) {
double distance = SphericalDistanceLibrary.distance(s.getVertex().getCoordinate(), sv.getCoordinate());
ret = distance < hop.getServiceAreaRadius();
}
if (hop.hasServiceArea() && hop.getServiceArea().contains(orig) && directServices.get(hop.getPattern()) == null) {
directServices.put(hop.getPattern(), hop);
}
return ret;
}

@Override
public void vertexVisitor(State state) {
if (state.getVertex() instanceof TransitStop && !(state.getVertex() instanceof TemporaryVertex)) {
transitStopStates.add(state);
}
}

protected void streetSearch(RoutingRequest rr) {
transitStopStates.clear();
super.streetSearch(rr);
createDirectHopsToStops(rr);
}

private void createDirectHopsToStops(RoutingRequest opt) {
Collection<PatternHop> services = directServices.values();
for (State state : transitStopStates) {
Vertex v = state.getVertex();
Point dest = GeometryUtils.getGeometryFactory().createPoint(v.getCoordinate());
for (PatternHop hop : services) {
if (hop.getServiceArea().contains(dest)) {
TransitStop fromStop, toStop;
if (opt.arriveBy) {
StreetVertex toVertex = findFirstStreetVertex(opt.rctx, true);
toStop = getTemporaryStop(toVertex, null, opt.rctx, opt);
fromStop = (TransitStop) v;
} else {
StreetVertex fromVertex = findFirstStreetVertex(opt.rctx, false);
fromStop = getTemporaryStop(fromVertex, null, opt.rctx, opt);
toStop = (TransitStop) v;
}
createDirectHop(opt, hop, fromStop, toStop, new GraphPath(state, true));
}
}
}
double distance = SphericalDistanceLibrary.distance(s.getVertex().getCoordinate(), sv.getCoordinate());
return distance < hop.getServiceAreaRadius();
}

@Override
Expand Down
Expand Up @@ -167,6 +167,8 @@ protected GtfsFlexGraphModifier(Graph graph) {
public void findExtraHops(RoutingRequest rr, Map<PatternHop, State> patternHopStateMap) {
}

public void vertexVisitor(State state) {}

/**
* Create temporary edges and vertices from the origin into the transit network.
*
Expand All @@ -177,6 +179,8 @@ public void createForwardHops(RoutingRequest request) {
RoutingRequest forward = request.clone();
forward.setMode(getMode());
forward.setArriveBy(false);
// allow discovery of stations even with car mode
forward.enterStationsWithCar = true;
streetSearch(forward);
}

Expand All @@ -190,10 +194,11 @@ public void createBackwardHops(RoutingRequest request) {
RoutingRequest backward = request.clone();
backward.setMode(getMode());
backward.setArriveBy(true);
backward.enterStationsWithCar = true;
streetSearch(backward);
}

private void streetSearch(RoutingRequest rr) {
protected void streetSearch(RoutingRequest rr) {
for(Pair<State, PatternHop> p : getClosestPatternHops(rr)) {
State s = p.getKey();
PatternHop hop = p.getValue();
Expand Down Expand Up @@ -267,6 +272,7 @@ public void visitEdge(Edge edge, State state) {

@Override
public void visitVertex(State state) {
vertexVisitor(state);
}

@Override
Expand Down

0 comments on commit 552017c

Please sign in to comment.