diff --git a/src/main/java/org/opentripplanner/routing/impl/HSLFareServiceImpl.java b/src/main/java/org/opentripplanner/routing/impl/HSLFareServiceImpl.java index d9e763a9efd..c07a2542f15 100644 --- a/src/main/java/org/opentripplanner/routing/impl/HSLFareServiceImpl.java +++ b/src/main/java/org/opentripplanner/routing/impl/HSLFareServiceImpl.java @@ -27,6 +27,7 @@ the License, or (at your option) any later version. import org.opentripplanner.routing.core.FareRuleSet; import org.opentripplanner.routing.core.State; import org.opentripplanner.routing.edgetype.HopEdge; +import org.opentripplanner.routing.edgetype.TransitBoardAlight; import org.opentripplanner.routing.graph.Edge; import org.opentripplanner.routing.spt.GraphPath; import org.opentripplanner.routing.impl.DefaultFareServiceImpl; @@ -50,10 +51,13 @@ protected List createRides(GraphPath path) { boolean newRide = true; for (State state : path.states) { Edge edge = state.getBackEdge(); - if (!(edge instanceof HopEdge)) { + if (edge instanceof TransitBoardAlight) { newRide = true; continue; } + if (!(edge instanceof HopEdge)) { + continue; + } HopEdge hEdge = (HopEdge) edge; if (newRide == true) { ride = new Ride(); @@ -101,13 +105,22 @@ protected FareAndId getBestFareAndId(FareType fareType, List rides, Collec /* HSL specific logig: all exception routes start and end from the defined zone set, but visit temporarily (maybe 1 stop only) an 'external' zone */ + float bestSpecialFare = Float.POSITIVE_INFINITY; Set ruleZones = null; for (FareRuleSet ruleSet : fareRules) { if(ruleSet.getRoutes().contains(ride.route) && ruleSet.getContains().contains(ride.startZone) && ruleSet.getContains().contains(ride.endZone)) { - ruleZones = ruleSet.getContains(); - break; + // check validity of this special rule and that it is the cheapest applicable one + FareAttribute attribute = ruleSet.getFareAttribute(); + if (!attribute.isTransferDurationSet() || + lastRideStartTime - startTime < attribute.getTransferDuration()) { + float newFare = getFarePrice(attribute, fareType); + if (newFare < bestSpecialFare) { + bestSpecialFare = newFare; + ruleZones = ruleSet.getContains(); + } + } } } if (ruleZones != null) { // the special case