use of org.opentripplanner.routing.graph.Graph in project OpenTripPlanner by opentripplanner.
the class InputStreamGraphSource method loadGraph.
/**
* Do the actual operation of graph loading. Load configuration if present, and startup the
* router with the help of the router lifecycle manager.
*/
private Router loadGraph() {
final Graph newGraph;
try (InputStream is = streams.getGraphInputStream()) {
LOG.info("Loading graph...");
try {
newGraph = Graph.load(new ObjectInputStream(is), loadLevel, streetVertexIndexFactory);
} catch (Exception ex) {
LOG.error("Exception while loading graph '{}'.", routerId, ex);
return null;
}
newGraph.routerId = (routerId);
} catch (IOException e) {
LOG.warn("Graph file not found or not openable for routerId '{}': {}", routerId, e);
return null;
}
// Even if a config file is not present on disk one could be bundled inside.
try (InputStream is = streams.getConfigInputStream()) {
JsonNode config = MissingNode.getInstance();
// TODO reuse the exact same JSON loader from OTPConfigurator
ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
if (is != null) {
config = mapper.readTree(is);
} else if (newGraph.routerConfig != null) {
config = mapper.readTree(newGraph.routerConfig);
}
Router newRouter = new Router(routerId, newGraph);
newRouter.startup(config);
return newRouter;
} catch (IOException e) {
LOG.error("Can't read config file.");
LOG.error(e.getMessage());
return null;
}
}
use of org.opentripplanner.routing.graph.Graph in project OpenTripPlanner by opentripplanner.
the class SimpleStreetSplitter method link.
/**
* Link this vertex into the graph
*/
public boolean link(Vertex vertex, TraverseMode traverseMode, RoutingRequest options) {
// find nearby street edges
// TODO: we used to use an expanding-envelope search, which is more efficient in
// dense areas. but first let's see how inefficient this is. I suspect it's not too
// bad and the gains in simplicity are considerable.
final double radiusDeg = SphericalDistanceLibrary.metersToDegrees(MAX_SEARCH_RADIUS_METERS);
Envelope env = new Envelope(vertex.getCoordinate());
// Perform a simple local equirectangular projection, so distances are expressed in degrees latitude.
final double xscale = Math.cos(vertex.getLat() * Math.PI / 180);
// Expand more in the longitude direction than the latitude direction to account for converging meridians.
env.expandBy(radiusDeg / xscale, radiusDeg);
final double DUPLICATE_WAY_EPSILON_DEGREES = SphericalDistanceLibrary.metersToDegrees(DUPLICATE_WAY_EPSILON_METERS);
final TraverseModeSet traverseModeSet;
if (traverseMode == TraverseMode.BICYCLE) {
traverseModeSet = new TraverseModeSet(traverseMode, TraverseMode.WALK);
} else {
traverseModeSet = new TraverseModeSet(traverseMode);
}
// We sort the list of candidate edges by distance to the stop
// This should remove any issues with things coming out of the spatial index in different orders
// Then we link to everything that is within DUPLICATE_WAY_EPSILON_METERS of of the best distance
// so that we capture back edges and duplicate ways.
List<StreetEdge> candidateEdges = idx.query(env).stream().filter(streetEdge -> streetEdge instanceof StreetEdge).map(edge -> (StreetEdge) edge).filter(edge -> edge.canTraverse(traverseModeSet) && // only link to edges still in the graph.
edge.getToVertex().getIncoming().contains(edge)).collect(Collectors.toList());
// Make a map of distances to all edges.
final TIntDoubleMap distances = new TIntDoubleHashMap();
for (StreetEdge e : candidateEdges) {
distances.put(e.getId(), distance(vertex, e, xscale));
}
// Sort the list.
Collections.sort(candidateEdges, (o1, o2) -> {
double diff = distances.get(o1.getId()) - distances.get(o2.getId());
// A Comparator must return an integer but our distances are doubles.
if (diff < 0)
return -1;
if (diff > 0)
return 1;
return 0;
});
// find the closest candidate edges
if (candidateEdges.isEmpty() || distances.get(candidateEdges.get(0).getId()) > radiusDeg) {
// We only link to stops if we are searching for origin/destination and for that we need transitStopIndex.
if (destructiveSplitting || transitStopIndex == null) {
return false;
}
LOG.debug("No street edge was found for {}", vertex);
// We search for closest stops (since this is only used in origin/destination linking if no edges were found)
// in the same way the closest edges are found.
List<TransitStop> candidateStops = new ArrayList<>();
transitStopIndex.query(env).forEach(candidateStop -> candidateStops.add((TransitStop) candidateStop));
final TIntDoubleMap stopDistances = new TIntDoubleHashMap();
for (TransitStop t : candidateStops) {
stopDistances.put(t.getIndex(), distance(vertex, t, xscale));
}
Collections.sort(candidateStops, (o1, o2) -> {
double diff = stopDistances.get(o1.getIndex()) - stopDistances.get(o2.getIndex());
if (diff < 0) {
return -1;
}
if (diff > 0) {
return 1;
}
return 0;
});
if (candidateStops.isEmpty() || stopDistances.get(candidateStops.get(0).getIndex()) > radiusDeg) {
LOG.debug("Stops aren't close either!");
return false;
} else {
List<TransitStop> bestStops = Lists.newArrayList();
// Add stops until there is a break of epsilon meters.
// we do this to enforce determinism. if there are a lot of stops that are all extremely close to each other,
// we want to be sure that we deterministically link to the same ones every time. Any hard cutoff means things can
// fall just inside or beyond the cutoff depending on floating-point operations.
int i = 0;
do {
bestStops.add(candidateStops.get(i++));
} while (i < candidateStops.size() && stopDistances.get(candidateStops.get(i).getIndex()) - stopDistances.get(candidateStops.get(i - 1).getIndex()) < DUPLICATE_WAY_EPSILON_DEGREES);
for (TransitStop stop : bestStops) {
LOG.debug("Linking vertex to stop: {}", stop.getName());
makeTemporaryEdges((TemporaryStreetLocation) vertex, stop);
}
return true;
}
} else {
// find the best edges
List<StreetEdge> bestEdges = Lists.newArrayList();
// add edges until there is a break of epsilon meters.
// we do this to enforce determinism. if there are a lot of edges that are all extremely close to each other,
// we want to be sure that we deterministically link to the same ones every time. Any hard cutoff means things can
// fall just inside or beyond the cutoff depending on floating-point operations.
int i = 0;
do {
bestEdges.add(candidateEdges.get(i++));
} while (i < candidateEdges.size() && distances.get(candidateEdges.get(i).getId()) - distances.get(candidateEdges.get(i - 1).getId()) < DUPLICATE_WAY_EPSILON_DEGREES);
for (StreetEdge edge : bestEdges) {
link(vertex, edge, xscale, options);
}
// Warn if a linkage was made, but the linkage was suspiciously long.
if (vertex instanceof TransitStop) {
double distanceDegreesLatitude = distances.get(candidateEdges.get(0).getId());
int distanceMeters = (int) SphericalDistanceLibrary.degreesLatitudeToMeters(distanceDegreesLatitude);
if (distanceMeters > WARNING_DISTANCE_METERS) {
// Registering an annotation but not logging because tests produce thousands of these warnings.
graph.addBuilderAnnotation(new StopLinkedTooFar((TransitStop) vertex, distanceMeters));
}
}
return true;
}
}
use of org.opentripplanner.routing.graph.Graph in project OpenTripPlanner by opentripplanner.
the class GraphServiceTest method testGraphServiceMemoryRouterConfig.
@Test
public final void testGraphServiceMemoryRouterConfig() throws IOException {
ObjectMapper mapper = new ObjectMapper();
JsonNode buildConfig = MissingNode.getInstance();
ObjectNode routerConfig = mapper.createObjectNode();
routerConfig.put("timeout", 8);
EmbedConfig embedConfig = new EmbedConfig(buildConfig, routerConfig);
embedConfig.buildGraph(emptyGraph, null);
GraphService graphService = new GraphService();
graphService.registerGraph("A", new MemoryGraphSource("A", emptyGraph));
assertEquals(1, graphService.getRouterIds().size());
Graph graph = graphService.getRouter("A").graph;
assertNotNull(graph);
assertEquals(emptyGraph, graph);
assertEquals("A", emptyGraph.routerId);
JsonNode graphRouterConfig = mapper.readTree(graph.routerConfig);
assertEquals(graphRouterConfig, routerConfig);
assertEquals(graphRouterConfig.get("timeout"), routerConfig.get("timeout"));
}
use of org.opentripplanner.routing.graph.Graph in project OpenTripPlanner by opentripplanner.
the class GraphServiceTest method testGraphServiceFile.
@Test
public final void testGraphServiceFile() throws IOException {
// Create a GraphService and a GraphSourceFactory
GraphService graphService = new GraphService();
InputStreamGraphSource.FileFactory graphSourceFactory = new InputStreamGraphSource.FileFactory(basePath);
graphSourceFactory.save("A", new ByteArrayInputStream(emptyGraphData));
// Check if the graph has been saved
assertTrue(new File(new File(basePath, "A"), InputStreamGraphSource.GRAPH_FILENAME).canRead());
// Register this empty graph, reloading it from disk
boolean registered = graphService.registerGraph("A", graphSourceFactory.createGraphSource("A"));
assertTrue(registered);
// Check if the loaded graph is the one we saved earlier
Graph graph = graphService.getRouter("A").graph;
assertNotNull(graph);
assertEquals("A", graph.routerId);
assertEquals(0, graph.getVertices().size());
assertEquals(1, graphService.getRouterIds().size());
// Save A again, with more data this time
int verticesCount = smallGraph.getVertices().size();
int edgesCount = smallGraph.getEdges().size();
graphSourceFactory.save("A", new ByteArrayInputStream(smallGraphData));
// Force a reload, get again the graph
graphService.reloadGraphs(false, true);
graph = graphService.getRouter("A").graph;
// Check if loaded graph is the one modified
assertEquals(verticesCount, graph.getVertices().size());
assertEquals(edgesCount, graph.getEdges().size());
// Remove the file from disk and reload
boolean deleted = new File(new File(basePath, "A"), InputStreamGraphSource.GRAPH_FILENAME).delete();
assertTrue(deleted);
graphService.reloadGraphs(false, true);
// Check that the graph have been evicted
assertEquals(0, graphService.getRouterIds().size());
// Register it manually
registered = graphService.registerGraph("A", graphSourceFactory.createGraphSource("A"));
// Check that it fails again (file still deleted)
assertFalse(registered);
assertEquals(0, graphService.getRouterIds().size());
// Re-save the graph file, register it again
graphSourceFactory.save("A", new ByteArrayInputStream(smallGraphData));
registered = graphService.registerGraph("A", graphSourceFactory.createGraphSource("A"));
// This time registering is OK
assertTrue(registered);
assertEquals(1, graphService.getRouterIds().size());
// Evict the graph, should be OK
boolean evicted = graphService.evictRouter("A");
assertTrue(evicted);
assertEquals(0, graphService.getRouterIds().size());
}
use of org.opentripplanner.routing.graph.Graph in project OpenTripPlanner by opentripplanner.
the class TripTimesTest method testBikesAllowed.
@Test
public void testBikesAllowed() {
Graph graph = new Graph();
Trip trip = new Trip();
Route route = new Route();
trip.setRoute(route);
List<StopTime> stopTimes = Arrays.asList(new StopTime(), new StopTime());
TripTimes s = new TripTimes(trip, stopTimes, new Deduplicator());
RoutingRequest request = new RoutingRequest(TraverseMode.BICYCLE);
Vertex v = new SimpleConcreteVertex(graph, "", 0.0, 0.0);
request.setRoutingContext(graph, v, v);
State s0 = new State(request);
assertFalse(s.tripAcceptable(s0, 0));
BikeAccess.setForTrip(trip, BikeAccess.ALLOWED);
assertTrue(s.tripAcceptable(s0, 0));
BikeAccess.setForTrip(trip, BikeAccess.NOT_ALLOWED);
assertFalse(s.tripAcceptable(s0, 0));
}
Aggregations