/* 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.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.gtfs.model.FareAttribute;
import org.opentripplanner.routing.core.FareRuleSet;
import org.opentripplanner.routing.core.TraverseMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SFBayFareServiceImpl extends DefaultFareServiceImpl {
public SFBayFareServiceImpl(
HashMap<AgencyAndId, FareRuleSet> fareRules,
HashMap<AgencyAndId, FareAttribute> fareAttributes) {
super(fareRules, fareAttributes);
}
private static final long serialVersionUID = 20120229L;
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<String> SFMTA_BART_TRANSFER_STOPS = new HashSet<String>(Arrays.asList(
"EMBR", "MONT", "POWL", "CIVC", "16TH", "24TH", "GLEN", "BALB", "DALY"));
public static final String SFMTA_BART_FREE_TRANSFER_STOP = "DALY";
@Override
public float getLowestCost(List<Ride> rides) {
List<Ride> bartBlock = null;
Long sfmtaTransferIssued = null;
Long alightedBart = null;
String alightedBartStop = null;
float cost = 0f;
String agencyId = null;
for (Ride ride : rides) {
agencyId = ride.route.getAgencyId();
if (agencyId.equals("BART")) {
if (bartBlock == null) {
bartBlock = new ArrayList<Ride>();
}
bartBlock.add(ride);
alightedBart = ride.endTime;
alightedBartStop = ride.lastStop.getId().getId();
} else { // non-BART agency
if (bartBlock != null) {
// finalize outstanding bart block, if any
cost += calculateCost(bartBlock);
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) {
sfmtaTransferIssued = ride.startTime;
if (alightedBart != null &&
alightedBart + BART_TRANSFER_DURATION > ride.startTime &&
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(bartBlock);
}
return cost;
}
}