org.opentripplanner.routing.fares.impl.SFBayFareServiceImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
package org.opentripplanner.routing.fares.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Currency;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.opentripplanner.routing.core.Fare;
import org.opentripplanner.routing.core.FareRuleSet;
import org.opentripplanner.routing.core.TraverseMode;
import org.opentripplanner.routing.core.Fare.FareType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SFBayFareServiceImpl extends DefaultFareServiceImpl {
public SFBayFareServiceImpl(Collection regularFareRules) {
addFareRules(FareType.regular, regularFareRules);
}
private static final long serialVersionUID = 20120229L;
@SuppressWarnings("unused")
private static final Logger LOG = LoggerFactory.getLogger(SFBayFareServiceImpl.class);
public static final int SFMTA_TRANSFER_DURATION = 60 * 90;
public static final int BART_TRANSFER_DURATION = 60 * 60;
public static final float SFMTA_BASE_FARE = 2.00f;
public static final float CABLE_CAR_FARE = 5.00f;
public static final float AIRBART_FARE = 3.00f;
public static final float SFMTA_BART_TRANSFER_FARE = 1.75f;
public static final Set SFMTA_BART_TRANSFER_STOPS = new HashSet(Arrays.asList(
"EMBR", "MONT", "POWL", "CIVC", "16TH", "24TH", "GLEN", "BALB", "DALY"));
public static final String SFMTA_BART_FREE_TRANSFER_STOP = "DALY";
@Override
protected boolean populateFare(Fare fare, Currency currency, FareType fareType, List rides,
Collection fareRules) {
float lowestCost = getLowestCost(fareType, rides, fareRules);
if(lowestCost != Float.POSITIVE_INFINITY) {
fare.addFare(fareType, getMoney(currency, lowestCost));
return true;
}
return false;
}
@Override
protected float getLowestCost(FareType fareType, List rides,
Collection fareRules) {
List bartBlock = null;
Long sfmtaTransferIssued = null;
Long alightedBart = null;
String alightedBartStop = null;
float cost = 0f;
String agencyId = null;
for (Ride ride : rides) {
agencyId = ride.route.getFeedId();
if (agencyId.equals("BART")) {
if (bartBlock == null) {
bartBlock = new ArrayList();
}
bartBlock.add(ride);
alightedBart = ride.endTime.toEpochSecond();
alightedBartStop = ride.lastStop.getId().getId();
} else { // non-BART agency
if (bartBlock != null) {
// finalize outstanding bart block, if any
cost += calculateCost(fareType, bartBlock, fareRules);
bartBlock = null;
}
if (agencyId.equals("SFMTA")) {
if (ride.classifier == TraverseMode.CABLE_CAR) {
// no transfers issued or accepted
cost += CABLE_CAR_FARE;
} else if (sfmtaTransferIssued == null ||
sfmtaTransferIssued + SFMTA_TRANSFER_DURATION < ride.endTime.toEpochSecond()) {
sfmtaTransferIssued = ride.startTime.toEpochSecond();
if (alightedBart != null &&
alightedBart + BART_TRANSFER_DURATION > ride.startTime.toEpochSecond() &&
SFMTA_BART_TRANSFER_STOPS.contains(alightedBartStop)) {
// discount for BART to Muni transfer
if (alightedBartStop.equals(SFMTA_BART_FREE_TRANSFER_STOP)) {
// no cost to ride Muni
} else {
cost += SFMTA_BART_TRANSFER_FARE;
}
} else {
// no transfer, basic fare
cost += SFMTA_BASE_FARE;
}
} else {
// SFMTA-SFMTA non-cable-car transfer within time limit, no cost
}
} else if (agencyId.equals("AirBART")) {
cost += AIRBART_FARE;
}
}
}
if (bartBlock != null) {
// finalize outstanding bart block, if any
cost += calculateCost(fareType, bartBlock, fareRules);
}
return cost;
}
}