/* 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.algorithm;
import junit.framework.TestCase;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.gtfs.model.calendar.CalendarServiceData;
import org.opentripplanner.ConstantsForTests;
import org.opentripplanner.gtfs.GtfsContext;
import org.opentripplanner.gtfs.GtfsLibrary;
import org.opentripplanner.routing.core.Fare;
import org.opentripplanner.routing.core.Fare.FareType;
import org.opentripplanner.routing.core.FareComponent;
import org.opentripplanner.routing.core.Money;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.core.WrappedCurrency;
import org.opentripplanner.routing.edgetype.factory.GTFSPatternHopFactory;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.impl.SeattleFareServiceFactory;
import org.opentripplanner.routing.services.FareService;
import org.opentripplanner.routing.spt.GraphPath;
import org.opentripplanner.routing.spt.ShortestPathTree;
import org.opentripplanner.util.TestUtils;
import java.io.File;
import java.util.List;
public class TestFares extends TestCase {
private AStar aStar = new AStar();
public void testBasic() throws Exception {
Graph gg = new Graph();
GtfsContext context = GtfsLibrary.readGtfs(new File(ConstantsForTests.CALTRAIN_GTFS));
GTFSPatternHopFactory factory = new GTFSPatternHopFactory(context);
factory.run(gg);
gg.putService(CalendarServiceData.class, GtfsLibrary.createCalendarServiceData(context.getDao()));
RoutingRequest options = new RoutingRequest();
String feedId = gg.getFeedIds().iterator().next();
long startTime = TestUtils.dateInSeconds("America/Los_Angeles", 2009, 8, 7, 12, 0, 0);
options.dateTime = startTime;
options.setRoutingContext(gg, feedId + ":Millbrae Caltrain", feedId + ":Mountain View Caltrain");
ShortestPathTree spt;
GraphPath path = null;
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(feedId + ":Mountain View Caltrain"), true);
FareService fareService = gg.getService(FareService.class);
Fare cost = fareService.getCost(path);
assertEquals(cost.getFare(FareType.regular), new Money(new WrappedCurrency("USD"), 425));
}
public void testPortland() throws Exception {
Graph gg = ConstantsForTests.getInstance().getPortlandGraph();
String feedId = gg.getFeedIds().iterator().next();
RoutingRequest options = new RoutingRequest();
ShortestPathTree spt;
GraphPath path = null;
long startTime = TestUtils.dateInSeconds("America/Los_Angeles", 2009, 11, 1, 12, 0, 0);
options.dateTime = startTime;
options.setRoutingContext(gg, feedId + ":10579", feedId + ":8371");
// from zone 3 to zone 2
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(feedId + ":8371"), true);
assertNotNull(path);
FareService fareService = gg.getService(FareService.class);
Fare cost = fareService.getCost(path);
assertEquals(new Money(new WrappedCurrency("USD"), 200), cost.getFare(FareType.regular));
// long trip
startTime = TestUtils.dateInSeconds("America/Los_Angeles", 2009, 11, 1, 14, 0, 0);
options.dateTime = startTime;
options.setRoutingContext(gg, feedId + ":8389", feedId + ":1252");
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(feedId + ":1252"), true);
assertNotNull(path);
cost = fareService.getCost(path);
//assertEquals(cost.getFare(FareType.regular), new Money(new WrappedCurrency("USD"), 460));
// complex trip
options.maxTransfers = 5;
startTime = TestUtils.dateInSeconds("America/Los_Angeles", 2009, 11, 1, 14, 0, 0);
options.dateTime = startTime;
options.setRoutingContext(gg, feedId + ":10428", feedId + ":4231");
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(feedId + ":4231"), true);
assertNotNull(path);
cost = fareService.getCost(path);
//
// this is commented out because portland's fares are, I think, broken in the gtfs. see
// thread on gtfs-changes.
// assertEquals(cost.getFare(FareType.regular), new Money(new WrappedCurrency("USD"), 430));
}
public void testKCM() throws Exception {
Graph gg = new Graph();
GtfsContext context = GtfsLibrary.readGtfs(new File(ConstantsForTests.KCM_GTFS));
GTFSPatternHopFactory factory = new GTFSPatternHopFactory(context);
factory.setFareServiceFactory(new SeattleFareServiceFactory());
factory.run(gg);
gg.putService(CalendarServiceData.class, GtfsLibrary.createCalendarServiceData(context.getDao()));
RoutingRequest options = new RoutingRequest();
String feedId = gg.getFeedIds().iterator().next();
String vertex0 = feedId + ":2010";
String vertex1 = feedId + ":2140";
ShortestPathTree spt;
GraphPath path = null;
FareService fareService = gg.getService(FareService.class);
long offPeakStartTime = TestUtils.dateInSeconds("America/Los_Angeles", 2016, 5, 24, 5, 0, 0);
options.dateTime = offPeakStartTime;
options.setRoutingContext(gg, vertex0, vertex1);
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(vertex1), true);
Fare costOffPeak = fareService.getCost(path);
assertEquals(costOffPeak.getFare(FareType.regular), new Money(new WrappedCurrency("USD"), 250));
long onPeakStartTime = TestUtils.dateInSeconds("America/Los_Angeles", 2016, 5, 24, 8, 0, 0);
options.dateTime = onPeakStartTime;
options.setRoutingContext(gg, vertex0, vertex1);
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(vertex1), true);
Fare costOnPeak = fareService.getCost(path);
assertEquals(costOnPeak.getFare(FareType.regular), new Money(new WrappedCurrency("USD"), 275));
}
public void testFareComponent() throws Exception {
Graph gg = new Graph();
GtfsContext context = GtfsLibrary.readGtfs(new File(ConstantsForTests.FARE_COMPONENT_GTFS));
GTFSPatternHopFactory factory = new GTFSPatternHopFactory(context);
factory.run(gg);
gg.putService(CalendarServiceData.class, GtfsLibrary.createCalendarServiceData(context.getDao()));
String feedId = gg.getFeedIds().iterator().next();
RoutingRequest options = new RoutingRequest();
long startTime = TestUtils.dateInSeconds("America/Los_Angeles", 2009, 8, 7, 12, 0, 0);
options.dateTime = startTime;
ShortestPathTree spt;
GraphPath path = null;
Fare fare = null;
List<FareComponent> fareComponents = null;
FareService fareService = gg.getService(FareService.class);
Money tenUSD = new Money(new WrappedCurrency("USD"), 1000);
// A -> B, base case
options.setRoutingContext(gg, feedId+":A", feedId+":B");
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(feedId+":B"), true);
fare = fareService.getCost(path);
fareComponents = fare.getDetails(FareType.regular);
assertEquals(fareComponents.size(), 1);
assertEquals(fareComponents.get(0).price, tenUSD);
assertEquals(fareComponents.get(0).fareId, new AgencyAndId(feedId, "AB"));
assertEquals(fareComponents.get(0).routes.get(0), new AgencyAndId("agency", "1"));
// D -> E, null case
options.setRoutingContext(gg, feedId+":D", feedId+":E");
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(feedId+":E"), true);
fare = fareService.getCost(path);
assertNull(fare);
// A -> C, 2 components in a path
options.setRoutingContext(gg, feedId+":A", feedId+":C");
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(feedId+":C"), true);
fare = fareService.getCost(path);
fareComponents = fare.getDetails(FareType.regular);
assertEquals(fareComponents.size(), 2);
assertEquals(fareComponents.get(0).price, tenUSD);
assertEquals(fareComponents.get(0).fareId, new AgencyAndId(feedId, "AB"));
assertEquals(fareComponents.get(0).routes.get(0), new AgencyAndId("agency", "1"));
assertEquals(fareComponents.get(1).price, tenUSD);
assertEquals(fareComponents.get(1).fareId, new AgencyAndId(feedId, "BC"));
assertEquals(fareComponents.get(1).routes.get(0), new AgencyAndId("agency", "2"));
// B -> D, 2 fully connected components
options.setRoutingContext(gg, feedId+":B", feedId+":D");
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(feedId+":D"), true);
fare = fareService.getCost(path);
fareComponents = fare.getDetails(FareType.regular);
assertEquals(fareComponents.size(), 1);
assertEquals(fareComponents.get(0).price, tenUSD);
assertEquals(fareComponents.get(0).fareId, new AgencyAndId(feedId, "BD"));
assertEquals(fareComponents.get(0).routes.get(0), new AgencyAndId("agency", "2"));
assertEquals(fareComponents.get(0).routes.get(1), new AgencyAndId("agency", "3"));
// E -> G, missing in between fare
options.setRoutingContext(gg, feedId+":E", feedId+":G");
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(feedId+":G"), true);
fare = fareService.getCost(path);
fareComponents = fare.getDetails(FareType.regular);
assertEquals(fareComponents.size(), 1);
assertEquals(fareComponents.get(0).price, tenUSD);
assertEquals(fareComponents.get(0).fareId, new AgencyAndId(feedId, "EG"));
assertEquals(fareComponents.get(0).routes.get(0), new AgencyAndId("agency", "5"));
assertEquals(fareComponents.get(0).routes.get(1), new AgencyAndId("agency", "6"));
// C -> E, missing fare after
options.setRoutingContext(gg, feedId+":C", feedId+":E");
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(feedId+":E"), true);
fare = fareService.getCost(path);
fareComponents = fare.getDetails(FareType.regular);
assertEquals(fareComponents.size(), 1);
assertEquals(fareComponents.get(0).price, tenUSD);
assertEquals(fareComponents.get(0).fareId, new AgencyAndId(feedId, "CD"));
assertEquals(fareComponents.get(0).routes.get(0), new AgencyAndId("agency", "3"));
// D -> G, missing fare before
options.setRoutingContext(gg, feedId+":D", feedId+":G");
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(feedId+":G"), true);
fare = fareService.getCost(path);
fareComponents = fare.getDetails(FareType.regular);
assertEquals(fareComponents.size(), 1);
assertEquals(fareComponents.get(0).price, tenUSD);
assertEquals(fareComponents.get(0).fareId, new AgencyAndId(feedId, "EG"));
assertEquals(fareComponents.get(0).routes.get(0), new AgencyAndId("agency", "5"));
assertEquals(fareComponents.get(0).routes.get(1), new AgencyAndId("agency", "6"));
// A -> D, use individual component parts
options.setRoutingContext(gg, feedId+":A", feedId+":D");
spt = aStar.getShortestPathTree(options);
path = spt.getPath(gg.getVertex(feedId+":D"), true);
fare = fareService.getCost(path);
fareComponents = fare.getDetails(FareType.regular);
assertEquals(fareComponents.size(), 2);
assertEquals(fareComponents.get(0).price, tenUSD);
assertEquals(fareComponents.get(0).fareId, new AgencyAndId(feedId, "AB"));
assertEquals(fareComponents.get(0).routes.get(0), new AgencyAndId("agency", "1"));
assertEquals(fareComponents.get(1).price, tenUSD);
assertEquals(fareComponents.get(1).fareId, new AgencyAndId(feedId, "BD"));
assertEquals(fareComponents.get(1).routes.get(0), new AgencyAndId("agency", "2"));
assertEquals(fareComponents.get(1).routes.get(1), new AgencyAndId("agency", "3"));
}
}