routes.add(ride.route);
zones.addAll(ride.zones);
transfersUsed += 1;
}
FareAttribute bestAttribute = null;
float bestFare = Float.POSITIVE_INFINITY;
long tripTime = lastRideStartTime - startTime;
long journeyTime = lastRideEndTime - startTime;
// find the best fare that matches this set of rides
for (AgencyAndId fareId : fareAttributes.keySet()) {
// fares also don't really have an agency id, they will have the per-feed default id
if ( ! fareId.getAgencyId().equals(feedId))
continue;
FareRuleSet ruleSet = fareRules.get(fareId);
if (ruleSet == null || ruleSet.matches(startZone, endZone, zones, routes)) {
FareAttribute attribute = fareAttributes.get(fareId);
if (attribute.isTransfersSet() && attribute.getTransfers() < transfersUsed) {
continue;
}
// assume transfers are evaluated at boarding time,
// as trimet does
if (attribute.isTransferDurationSet() &&
tripTime > attribute.getTransferDuration()) {
continue;
}
if (attribute.isJourneyDurationSet() &&
journeyTime > attribute.getJourneyDuration()) {
continue;
}
float newFare = attribute.getPrice();
if (newFare < bestFare) {
bestAttribute = attribute;
bestFare = newFare;
}
}