use of org.onebusaway.gtfs.model.Trip in project OpenTripPlanner by opentripplanner.
the class OnBoardDepartServiceImpl method setupDepartOnBoard.
@Override
public Vertex setupDepartOnBoard(RoutingContext ctx) {
RoutingRequest opt = ctx.opt;
opt.rctx = ctx;
/* 1. Get the list of PatternHop for the given trip ID. */
AgencyAndId tripId = opt.startingTransitTripId;
Trip trip = ctx.graph.index.tripForId.get(tripId);
TripPattern tripPattern = ctx.graph.index.patternForTrip.get(trip);
if (tripPattern == null) {
// TODO Shouldn't we bailout on a normal trip plan here, returning null ?
throw new IllegalArgumentException("Unknown/invalid trip ID: " + tripId);
}
List<PatternHop> hops = tripPattern.getPatternHops();
// Origin point, optional
Double lon = opt.from.lng;
Double lat = opt.from.lat;
PatternStopVertex nextStop;
TripTimes bestTripTimes = null;
ServiceDay bestServiceDay = null;
int bestStopIndex = 0;
double fractionCovered;
LineString geomRemaining;
Coordinate point = lon == null || lat == null ? null : new Coordinate(lon, lat);
if (point != null) {
/*
* 2. Get the best hop from the list, given the parameters. Currently look for nearest hop,
* taking into account shape if available. If no shape are present, the computed hop and
* fraction may be a bit away from what it should be.
*/
PatternHop bestHop = null;
double minDist = Double.MAX_VALUE;
for (PatternHop hop : hops) {
LineString line = hop.getGeometry();
double dist = SphericalDistanceLibrary.fastDistance(point, line);
if (dist < minDist) {
minDist = dist;
bestHop = hop;
}
}
if (minDist > 1000)
LOG.warn("On-board depart: origin point suspiciously away from nearest trip shape ({} meters)", minDist);
else
LOG.info("On-board depart: origin point {} meters away from hop shape", minDist);
/*
* 3. Compute the fraction covered percentage of the current hop. This assume a constant
* trip speed alongside the whole hop: this should be quite precise for small hops
* (buses), a bit less for longer ones (long distance train). Shape linear distance is
* of no help here, as the unit is arbitrary (and probably usually a distance).
*/
LineString geometry = bestHop.getGeometry();
P2<LineString> geomPair = GeometryUtils.splitGeometryAtPoint(geometry, point);
geomRemaining = geomPair.second;
double total = SphericalDistanceLibrary.fastLength(geometry);
double remaining = SphericalDistanceLibrary.fastLength(geomRemaining);
fractionCovered = total > 0.0 ? (double) (1.0 - remaining / total) : 0.0;
nextStop = (PatternStopVertex) bestHop.getToVertex();
bestStopIndex = bestHop.getStopIndex();
/*
* 4. Compute service day based on given departure day/time relative to
* scheduled/real-time trip time for hop. This is needed as for some trips any service
* day can apply.
*/
int minDelta = Integer.MAX_VALUE;
int actDelta = 0;
for (ServiceDay serviceDay : ctx.serviceDays) {
TripPattern pattern = nextStop.getTripPattern();
Timetable timetable = pattern.getUpdatedTimetable(opt, serviceDay);
// Get the tripTimes including real-time updates for the serviceDay
TripTimes tripTimes = timetable.getTripTimes(timetable.getTripIndex(tripId));
int depTime = tripTimes.getDepartureTime(bestStopIndex);
int arrTime = tripTimes.getArrivalTime(bestStopIndex + 1);
int estTime = (int) Math.round(depTime * fractionCovered + arrTime * (1 - fractionCovered));
int time = serviceDay.secondsSinceMidnight(opt.dateTime);
/*
* TODO Weight differently early vs late time, as the probability of any transit
* being late is higher than being early. However, this has impact if your bus is
* more than 12h late, I don't think this would happen really often.
*/
int deltaTime = Math.abs(time - estTime);
if (deltaTime < minDelta) {
minDelta = deltaTime;
actDelta = time - estTime;
bestTripTimes = tripTimes;
bestServiceDay = serviceDay;
}
}
if (minDelta > 60000)
// Being more than 1h late should not happen often
LOG.warn("On-board depart: delta between scheduled/real-time and actual time suspiciously large: {} seconds.", actDelta);
else
LOG.info("On-board depart: delta between scheduled/real-time and actual time is {} seconds.", actDelta);
} else {
/* 2. Compute service day */
for (ServiceDay serviceDay : ctx.serviceDays) {
Timetable timetable = tripPattern.getUpdatedTimetable(opt, serviceDay);
// Get the tripTimes including real-time updates for the serviceDay
TripTimes tripTimes = timetable.getTripTimes(timetable.getTripIndex(tripId));
int depTime = tripTimes.getDepartureTime(0);
int arrTime = tripTimes.getArrivalTime(tripTimes.getNumStops() - 1);
int time = serviceDay.secondsSinceMidnight(opt.dateTime);
if (depTime <= time && time <= arrTime) {
bestTripTimes = tripTimes;
bestServiceDay = serviceDay;
}
}
if (bestServiceDay == null) {
throw new RuntimeException("Unable to determine on-board depart service day.");
}
int time = bestServiceDay.secondsSinceMidnight(opt.dateTime);
/*
* 3. Get the best hop from the list, given the parameters. This is done by finding the
* last hop that has not yet departed.
*/
PatternHop bestHop = null;
for (PatternHop hop : hops) {
int stopIndex = hop.getStopIndex();
int depTime = bestTripTimes.getDepartureTime(stopIndex);
int arrTime = bestTripTimes.getArrivalTime(stopIndex + 1);
if (time == arrTime) {
return ctx.graph.getVertex(hop.getEndStop().getId().toString());
} else if (depTime < time) {
bestHop = hop;
bestStopIndex = stopIndex;
} else if (time == depTime || bestTripTimes.getArrivalTime(bestStopIndex + 1) < time) {
return ctx.graph.getVertex(hop.getBeginStop().getId().toString());
} else {
break;
}
}
nextStop = (PatternStopVertex) bestHop.getToVertex();
LineString geometry = bestHop.getGeometry();
/*
* 4. Compute the fraction covered percentage of the current hop. Once again a constant
* trip speed is assumed. The linear distance of the shape is used, so the results are
* not 100% accurate. On the flip side, they are easy to compute and very well testable.
*/
int depTime = bestTripTimes.getDepartureTime(bestStopIndex);
int arrTime = bestTripTimes.getArrivalTime(bestStopIndex + 1);
fractionCovered = ((double) (time - depTime)) / ((double) (arrTime - depTime));
P2<LineString> geomPair = GeometryUtils.splitGeometryAtFraction(geometry, fractionCovered);
geomRemaining = geomPair.second;
if (geometry.isEmpty()) {
lon = Double.NaN;
lat = Double.NaN;
} else {
Coordinate start;
if (geomRemaining.isEmpty()) {
start = geometry.getCoordinateN(geometry.getNumPoints() - 1);
} else {
start = geomRemaining.getCoordinateN(0);
}
lon = start.x;
lat = start.y;
}
}
OnboardDepartVertex onboardDepart = new OnboardDepartVertex("on_board_depart", lon, lat);
OnBoardDepartPatternHop startHop = new OnBoardDepartPatternHop(onboardDepart, nextStop, bestTripTimes, bestServiceDay, bestStopIndex, fractionCovered);
startHop.setGeometry(geomRemaining);
return onboardDepart;
}
use of org.onebusaway.gtfs.model.Trip in project OpenTripPlanner by opentripplanner.
the class AlertPatch method remove.
public void remove(Graph graph) {
Agency agency = null;
if (feedId != null) {
Map<String, Agency> agencies = graph.index.agenciesForFeedId.get(feedId);
agency = this.agency != null ? agencies.get(this.agency) : null;
}
Route route = this.route != null ? graph.index.routeForId.get(this.route) : null;
Stop stop = this.stop != null ? graph.index.stopForId.get(this.stop) : null;
Trip trip = this.trip != null ? graph.index.tripForId.get(this.trip) : null;
if (route != null || trip != null || agency != null) {
Collection<TripPattern> tripPatterns = null;
if (trip != null) {
tripPatterns = new LinkedList<TripPattern>();
TripPattern tripPattern = graph.index.patternForTrip.get(trip);
if (tripPattern != null) {
tripPatterns.add(tripPattern);
}
} else if (route != null) {
tripPatterns = graph.index.patternsForRoute.get(route);
} else {
// Find patterns for the feed.
tripPatterns = graph.index.patternsForFeedId.get(feedId);
}
if (tripPatterns != null) {
for (TripPattern tripPattern : tripPatterns) {
if (direction != null && !direction.equals(tripPattern.getDirection())) {
continue;
}
if (directionId != -1 && directionId != tripPattern.directionId) {
continue;
}
for (int i = 0; i < tripPattern.stopPattern.stops.length; i++) {
if (stop == null || stop.equals(tripPattern.stopPattern.stops[i])) {
graph.removeAlertPatch(tripPattern.boardEdges[i], this);
graph.removeAlertPatch(tripPattern.alightEdges[i], this);
}
}
}
}
} else if (stop != null) {
TransitStop transitStop = graph.index.stopVertexForStop.get(stop);
for (Edge edge : transitStop.getOutgoing()) {
if (edge instanceof PreBoardEdge) {
graph.removeAlertPatch(edge, this);
break;
}
}
for (Edge edge : transitStop.getIncoming()) {
if (edge instanceof PreAlightEdge) {
graph.removeAlertPatch(edge, this);
break;
}
}
}
}
use of org.onebusaway.gtfs.model.Trip in project OpenTripPlanner by opentripplanner.
the class TransferTable method getTransferTime.
/**
* Get the transfer time that should be used when transferring from a trip to another trip.
* Note that this function does not check whether another specific transfer exists with the
* same specificity, what is forbidden by the specifications.
* @param fromStop is the arriving stop
* @param toStop is the departing stop
* @param fromTrip is the arriving trip
* @param toTrip is the departing trip
* @param forwardInTime is true when moving forward in time; false when moving
* backwards in time (usually this will be the variable "boarding")
* @return the transfer time in seconds. May contain special (negative) values which meaning
* can be found in the StopTransfer.*_TRANSFER constants. If no transfer is found,
* StopTransfer.UNKNOWN_TRANSFER is returned.
*/
public int getTransferTime(Stop fromStop, Stop toStop, Trip fromTrip, Trip toTrip, boolean forwardInTime) {
checkNotNull(fromStop);
checkNotNull(toStop);
// Reverse from and to if we are moving backwards in time
if (!forwardInTime) {
Stop tempStop = fromStop;
fromStop = toStop;
toStop = tempStop;
Trip tempTrip = fromTrip;
fromTrip = toTrip;
toTrip = tempTrip;
}
// Get transfer time between the two stops
int transferTime = getTransferTime(fromStop.getId(), toStop.getId(), fromTrip, toTrip);
// Check parents of stops if no transfer was found
if (transferTime == StopTransfer.UNKNOWN_TRANSFER) {
// Find parent ids
AgencyAndId fromStopParentId = null;
AgencyAndId toStopParentId = null;
if (fromStop.getParentStation() != null && !fromStop.getParentStation().isEmpty()) {
// From stop has a parent
fromStopParentId = new AgencyAndId(fromStop.getId().getAgencyId(), fromStop.getParentStation());
}
if (toStop.getParentStation() != null && !toStop.getParentStation().isEmpty()) {
// To stop has a parent
toStopParentId = new AgencyAndId(toStop.getId().getAgencyId(), toStop.getParentStation());
}
// Check parent of from stop if no transfer was found
if (fromStopParentId != null) {
transferTime = getTransferTime(fromStopParentId, toStop.getId(), fromTrip, toTrip);
}
// Check parent of to stop if still no transfer was found
if (transferTime == StopTransfer.UNKNOWN_TRANSFER && toStopParentId != null) {
transferTime = getTransferTime(fromStop.getId(), toStopParentId, fromTrip, toTrip);
}
// Check parents of both stops if still no transfer was found
if (transferTime == StopTransfer.UNKNOWN_TRANSFER && fromStopParentId != null && toStopParentId != null) {
transferTime = getTransferTime(fromStopParentId, toStopParentId, fromTrip, toTrip);
}
}
return transferTime;
}
use of org.onebusaway.gtfs.model.Trip in project OpenTripPlanner by opentripplanner.
the class BikeAccessTest method testBikesAllowed.
@Test
public void testBikesAllowed() {
Trip trip = new Trip();
Route route = new Route();
trip.setRoute(route);
assertEquals(BikeAccess.UNKNOWN, BikeAccess.fromTrip(trip));
trip.setBikesAllowed(1);
assertEquals(BikeAccess.ALLOWED, BikeAccess.fromTrip(trip));
trip.setBikesAllowed(2);
assertEquals(BikeAccess.NOT_ALLOWED, BikeAccess.fromTrip(trip));
route.setBikesAllowed(1);
assertEquals(BikeAccess.NOT_ALLOWED, BikeAccess.fromTrip(trip));
trip.setBikesAllowed(0);
assertEquals(BikeAccess.ALLOWED, BikeAccess.fromTrip(trip));
route.setBikesAllowed(2);
assertEquals(BikeAccess.NOT_ALLOWED, BikeAccess.fromTrip(trip));
}
use of org.onebusaway.gtfs.model.Trip in project OpenTripPlanner by opentripplanner.
the class BikeAccessTest method setBikesAllowed.
@SuppressWarnings("deprecation")
@Test
public void setBikesAllowed() {
Trip trip = new Trip();
BikeAccess.setForTrip(trip, BikeAccess.ALLOWED);
assertEquals(1, trip.getBikesAllowed());
assertEquals(2, trip.getTripBikesAllowed());
BikeAccess.setForTrip(trip, BikeAccess.NOT_ALLOWED);
assertEquals(2, trip.getBikesAllowed());
assertEquals(1, trip.getTripBikesAllowed());
BikeAccess.setForTrip(trip, BikeAccess.UNKNOWN);
assertEquals(0, trip.getBikesAllowed());
assertEquals(0, trip.getTripBikesAllowed());
}
Aggregations