package org.opentripplanner.routing.graph;
import graphql.ExecutionResult;
import org.onebusaway.gtfs.model.Agency;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.gtfs.model.Route;
import org.onebusaway.gtfs.model.Stop;
import org.onebusaway.gtfs.model.Trip;
import org.opentripplanner.GtfsTest;
import org.opentripplanner.common.geometry.SphericalDistanceLibrary;
import org.opentripplanner.routing.edgetype.TripPattern;
import org.opentripplanner.routing.graph.Vertex;
import org.opentripplanner.routing.vertextype.TransitStop;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import java.util.List;
import java.util.Map;
/**
* Check that the graph index is created, that GTFS elements can be found in the index, and that
* the indexes are coherent with one another.
*
* TODO: The old transit index doesn't exist anymore, and the new one needs more tests.
*/
public class GraphIndexTest extends GtfsTest {
@Override
public String getFeedName() {
return "testagency.zip";
}
public void testIdLookup() {
/* Graph vertices */
for (Vertex vertex : graph.index.vertexForId.values()) {
if (vertex instanceof TransitStop) {
Stop stop = ((TransitStop)vertex).getStop();
Vertex index_vertex = graph.index.stopVertexForStop.get(stop);
assertEquals(index_vertex, vertex);
}
}
/* Agencies */
String feedId = graph.getFeedIds().iterator().next();
Agency agency;
agency = graph.index.agenciesForFeedId.get(feedId).get("azerty");
assertNull(agency);
agency = graph.index.agenciesForFeedId.get(feedId).get("agency");
assertEquals(agency.getId(), "agency");
assertEquals(agency.getName(), "Fake Agency");
/* Stops */
graph.index.stopForId.get(new AgencyAndId("X", "Y"));
/* Trips */
// graph.index.tripForId;
// graph.index.routeForId;
// graph.index.serviceForId;
// graph.index.patternForId;
}
/** Check that bidirectional relationships between TripPatterns and Trips, Routes, and Stops are coherent. */
public void testPatternsCoherent() {
for (Trip trip : graph.index.tripForId.values()) {
TripPattern pattern = graph.index.patternForTrip.get(trip);
assertTrue(pattern.getTrips().contains(trip));
}
/* This one depends on a feed where each TripPattern appears on only one route. */
for (Route route : graph.index.routeForId.values()) {
for (TripPattern pattern : graph.index.patternsForRoute.get(route)) {
assertEquals(pattern.route, route);
}
}
for (Stop stop : graph.index.stopForId.values()) {
for (TripPattern pattern : graph.index.patternsForStop.get(stop)) {
assertTrue(pattern.stopPattern.containsStop(stop.getId().toString()));
}
}
}
public void testSpatialIndex() {
String feedId = graph.getFeedIds().iterator().next();
Stop stopJ = graph.index.stopForId.get(new AgencyAndId(feedId, "J"));
Stop stopL = graph.index.stopForId.get(new AgencyAndId(feedId, "L"));
Stop stopM = graph.index.stopForId.get(new AgencyAndId(feedId, "M"));
TransitStop stopvJ = graph.index.stopVertexForStop.get(stopJ);
TransitStop stopvL = graph.index.stopVertexForStop.get(stopL);
TransitStop stopvM = graph.index.stopVertexForStop.get(stopM);
// There are a two other stops within 100 meters of stop J.
Envelope env = new Envelope(new Coordinate(stopJ.getLon(), stopJ.getLat()));
env.expandBy(SphericalDistanceLibrary.metersToLonDegrees(100, stopJ.getLat()),
SphericalDistanceLibrary.metersToDegrees(100));
List<TransitStop> stops = graph.index.stopSpatialIndex.query(env);
assertTrue(stops.contains(stopvJ));
assertTrue(stops.contains(stopvL));
assertTrue(stops.contains(stopvM));
assertTrue(stops.size() >= 3); // Query can overselect
}
public void testGraphQLSimple() {
String query =
"query Agency{" +
" agency(id: \"agency\"){" +
" name" +
" }" +
"}";
ExecutionResult result = graph.index.graphQL.execute(query);
assertTrue(result.getErrors().isEmpty());
Map<String, Object> data = (Map<String, Object>) result.getData();
assertEquals("Fake Agency", ((Map) data.get("agency")).get("name"));
}
public void testGraphQLNested() {
String query =
"query Agency{\n" +
" viewer {" +
" agency(id: \"agency\"){\n" +
" name\n" +
" routes{\n" +
" shortName" +
" }" +
" }}\n" +
"}\n";
ExecutionResult result = graph.index.graphQL.execute(query);
assertTrue(result.getErrors().isEmpty());
Map<String, Object> data = (Map<String, Object>) result.getData();
assertEquals(18, ((List) ((Map) ((Map) data.get("viewer")).get("agency")).get("routes")).size());
}
public void testGraphQLIntrospectionQuery() {
String query = " query IntrospectionQuery {\n"
+ " __schema {\n"
+ " queryType { name }\n"
+ " mutationType { name }\n"
+ " types {\n"
+ " ...FullType\n"
+ " }\n"
+ " directives {\n"
+ " name\n"
+ " description\n"
+ " args {\n"
+ " ...InputValue\n"
+ " }\n"
+ " onOperation\n"
+ " onFragment\n"
+ " onField\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ "\n"
+ " fragment FullType on __Type {\n"
+ " kind\n"
+ " name\n"
+ " description\n"
+ " fields {\n"
+ " name\n"
+ " description\n"
+ " args {\n"
+ " ...InputValue\n"
+ " }\n"
+ " type {\n"
+ " ...TypeRef\n"
+ " }\n"
+ " isDeprecated\n"
+ " deprecationReason\n"
+ " }\n"
+ " inputFields {\n"
+ " ...InputValue\n"
+ " }\n"
+ " interfaces {\n"
+ " ...TypeRef\n"
+ " }\n"
+ " enumValues {\n"
+ " name\n"
+ " description\n"
+ " isDeprecated\n"
+ " deprecationReason\n"
+ " }\n"
+ " possibleTypes {\n"
+ " ...TypeRef\n"
+ " }\n"
+ " }\n"
+ "\n"
+ " fragment InputValue on __InputValue {\n"
+ " name\n"
+ " description\n"
+ " type { ...TypeRef }\n"
+ " defaultValue\n"
+ " }\n"
+ "\n"
+ " fragment TypeRef on __Type {\n"
+ " kind\n"
+ " name\n"
+ " ofType {\n"
+ " kind\n"
+ " name\n"
+ " ofType {\n"
+ " kind\n"
+ " name\n"
+ " ofType {\n"
+ " kind\n"
+ " name\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " }";
ExecutionResult result = graph.index.graphQL.execute(query);
assertTrue(result.getErrors().isEmpty());
}
public void testParentStations() {
// graph.index.stopsForParentStation;
}
public void testLucene() {
// graph.index.luceneIndex
}
}