Skip to content

Commit

Permalink
VGF-19 implementation of call-n-ride which builds off deviated-fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
sdjacobs committed Aug 21, 2017
1 parent 64db083 commit fdad9cb
Show file tree
Hide file tree
Showing 6 changed files with 277 additions and 63 deletions.
Expand Up @@ -54,9 +54,15 @@ private void setIndices(PartialPatternHop hop) {
this.hop = hop;
}


@Override
public TripTimes getNextTrip(State s0, ServiceDay sd) {
if (hop.isUnscheduled()) {
RoutingRequest options = s0.getOptions();
Timetable timetable = getPattern().getUpdatedTimetable(options, sd);
int stopIndex = boarding ? getStopIndex() : getStopIndex() - 1;
int time = hop.getRunningTime(s0);
return timetable.getNextTrip(s0, sd, stopIndex, boarding, 0, 0, time);
}
double adjustment = boarding ? startIndex : -1 * (1 - endIndex);
RoutingRequest options = s0.getOptions();
Timetable timetable = getPattern().getUpdatedTimetable(options, sd);
Expand All @@ -66,6 +72,13 @@ public TripTimes getNextTrip(State s0, ServiceDay sd) {

@Override
public int calculateWait(State s0, ServiceDay sd, TripTimes tripTimes) {
if (hop.isUnscheduled()) {
if (boarding) {
return (int) (sd.time(tripTimes.getDepartureTime(getStopIndex())) - s0.getTimeSeconds());
} else {
return (int) (s0.getTimeSeconds() - sd.time(tripTimes.getArrivalTime(getStopIndex() - 1))) + hop.getRunningTime(s0);
}
}
int stopIndex = getStopIndex();
if (boarding) {
int offset = (int) Math.round(startIndex * (tripTimes.getRunningTime(stopIndex)));
Expand Down
Expand Up @@ -102,6 +102,12 @@ public PartialPatternHop(PatternHop hop, PatternStopVertex from, PatternStopVert
setGeometry(geometry);
}

// pass-thru for TemporaryDirectPatternHop
public PartialPatternHop(PatternHop hop, PatternStopVertex from, PatternStopVertex to, Stop fromStop, Stop toStop) {
super(from, to, fromStop, toStop, hop.getStopIndex(), hop.getRequestStops(), hop.getServiceAreaRadius(), hop.getServiceArea(), false);
this.originalHop = hop;
}

private void setGeometry(PatternHop hop, LengthIndexedLine line, double boardBuffer, double alightBuffer) {
double pointsPerMeter = (line.getEndIndex() - line.getStartIndex()) / SphericalDistanceLibrary.fastLength(hop.getGeometry());
double boardBufferPts = boardBuffer * pointsPerMeter;
Expand Down Expand Up @@ -153,7 +159,17 @@ public int getRunningTime(State s0) {

@Override
public LineString getDisplayGeometry() {
return displayGeometry;
if (displayGeometry != null) {
return displayGeometry;
}
return getGeometry();
}

/**
* Return true if "unscheduled" ie call-n-ride
*/
public boolean isUnscheduled() {
return false;
}

public boolean isDeviatedRouteService() {
Expand Down
@@ -0,0 +1,69 @@
/* 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.routing.edgetype.flex;

import com.vividsolutions.jts.geom.LineString;
import org.onebusaway.gtfs.model.Stop;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.edgetype.PatternHop;
import org.opentripplanner.routing.edgetype.TemporaryEdge;
import org.opentripplanner.routing.vertextype.PatternStopVertex;

/**
* This is associated with a PatternHop for stop_time information, but its geometry bears no
* relation to the route geometry. And its timing is approximate.
*/
public class TemporaryDirectPatternHop extends TemporaryPartialPatternHop implements TemporaryEdge {
private static final long serialVersionUID = 1L;

private int time;

public TemporaryDirectPatternHop(PatternHop hop, PatternStopVertex from, PatternStopVertex to, Stop fromStop, Stop toStop, LineString geometry, int time) {
super(hop, from, to, fromStop, toStop);
setGeometry(geometry);
this.time = time;
}

@Override
public State traverse(State s0) {
return super.traverse(s0);
}

@Override
public boolean isUnscheduled() {
return true;
}

@Override
public boolean isTrivial() {
return false;
}

@Override
public double timeLowerBound(RoutingRequest options) {
return time;
}

@Override
public int getRunningTime(State s0) {
return time;
}

@Override
public void dispose() {
fromv.removeOutgoing(this);
tov.removeIncoming(this);
}
}
Expand Up @@ -30,6 +30,11 @@ public TemporaryPartialPatternHop(PatternHop hop, PatternStopVertex from, Patter
super(hop, from, to, fromStop, toStop, startIndex, endIndex, startGeometry, startVehicleTime, endGeometry, endVehicleTime, buffer);
}

// pass-thru for TemporaryDirectPatternHop
public TemporaryPartialPatternHop(PatternHop hop, PatternStopVertex from, PatternStopVertex to, Stop fromStop, Stop toStop) {
super(hop, from, to, fromStop, toStop);
}

@Override
public void dispose() {
fromv.removeOutgoing(this);
Expand Down
Expand Up @@ -87,11 +87,24 @@ public TemporaryPartialPatternHop shortenEnd(RoutingRequest opt, State state, Te
PatternHop originalHop = hop.getOriginalHop();
GraphPath path = new GraphPath(state, false);
LengthIndexedLine line = new LengthIndexedLine(originalHop.getGeometry());
double startIndex = hop.getStartIndex();
double endIndex = line.project(state.getBackEdge().getToVertex().getCoordinate());
if (endIndex < hop.getStartIndex())
if (endIndex < startIndex)
return null;
return new TemporaryPartialPatternHop(originalHop, (PatternStopVertex) hop.getFromVertex(), to, hop.getBeginStop(), toStop,
hop.getStartIndex(), endIndex, hop.getStartGeometry(), hop.getStartVehicleTime(), geometry(path), path.getDuration(), opt.flagStopBufferSize);
// we may want to create a ~direct~ hop.
// let's say, create a direct hop if the distance we would travel on the route is < 100m todo
if (tooLittleOnRoute(originalHop, line, startIndex, endIndex)) {
createDirectHop(opt, originalHop);
return null;
} else {
return new TemporaryPartialPatternHop(originalHop, (PatternStopVertex) hop.getFromVertex(), to, hop.getBeginStop(), toStop,
startIndex, endIndex, hop.getStartGeometry(), hop.getStartVehicleTime(), geometry(path), path.getDuration(), opt.flagStopBufferSize);
}
}

private boolean tooLittleOnRoute(PatternHop originalHop, LengthIndexedLine line, double startIndex, double endIndex) {
double onRouteDistance = SphericalDistanceLibrary.fastLength((LineString) line.extractLine(startIndex, endIndex));
return onRouteDistance <= Math.min(100, originalHop.getDistance());
}

@Override
Expand Down

0 comments on commit fdad9cb

Please sign in to comment.