use of org.opentripplanner.routing.vertextype.TransitStopVertex in project OpenTripPlanner by opentripplanner.
the class RoutingServiceTest method testIdLookup.
public void testIdLookup() {
/* Graph vertices */
for (Vertex vertex : graph.getVertices()) {
if (vertex instanceof TransitStopVertex) {
Stop stop = ((TransitStopVertex) vertex).getStop();
Vertex index_vertex = graph.index.getStopVertexForStop().get(stop);
assertEquals(index_vertex, vertex);
}
}
/* Agencies */
String feedId = graph.getFeedIds().iterator().next();
Agency agency;
agency = graph.index.getAgencyForId(new FeedScopedId(feedId, "azerty"));
assertNull(agency);
agency = graph.index.getAgencyForId(new FeedScopedId(feedId, "agency"));
assertEquals(agency.getId().toString(), feedId + ":" + "agency");
assertEquals(agency.getName(), "Fake Agency");
/* Stops */
graph.index.getStopForId(new FeedScopedId("X", "Y"));
/* Trips */
// graph.index.tripForId;
// graph.index.routeForId;
// graph.index.serviceForId;
// graph.index.patternForId;
}
use of org.opentripplanner.routing.vertextype.TransitStopVertex in project OpenTripPlanner by opentripplanner.
the class RoutingServiceTest method testSpatialIndex.
public void testSpatialIndex() {
String feedId = graph.getFeedIds().iterator().next();
Stop stopJ = graph.index.getStopForId(new FeedScopedId(feedId, "J"));
Stop stopL = graph.index.getStopForId(new FeedScopedId(feedId, "L"));
Stop stopM = graph.index.getStopForId(new FeedScopedId(feedId, "M"));
TransitStopVertex stopvJ = graph.index.getStopVertexForStop().get(stopJ);
TransitStopVertex stopvL = graph.index.getStopVertexForStop().get(stopL);
TransitStopVertex stopvM = graph.index.getStopVertexForStop().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<TransitStopVertex> stops = graph.index.getStopSpatialIndex().query(env);
assertTrue(stops.contains(stopvJ));
assertTrue(stops.contains(stopvL));
assertTrue(stops.contains(stopvM));
// Query can overselect
assertTrue(stops.size() >= 3);
}
use of org.opentripplanner.routing.vertextype.TransitStopVertex in project OpenTripPlanner by opentripplanner.
the class SimpleStreetSplitter method link.
@SuppressWarnings("Convert2MethodRef")
public <T extends Vertex> void link(Class<T> type, Function<T, DataImportIssue> unlinkedIssueMapper) {
@SuppressWarnings("unchecked") List<T> vertices = graph.getVertices().stream().filter(type::isInstance).map(it -> (T) it).collect(Collectors.toList());
String actionName = "Link " + type.getSimpleName();
if (vertices.isEmpty()) {
LOG.info("{} skiped. No such data exist.", actionName);
return;
}
ProgressTracker progress = ProgressTracker.track(actionName, 500, vertices.size());
LOG.info(progress.startMessage());
for (T v : vertices) {
// Do not link vertices, which are already linked by TransitToTaggedStopsModule
boolean alreadyLinked = v.getOutgoing().stream().anyMatch(e -> e instanceof StreetTransitLink);
if (alreadyLinked) {
continue;
}
// Do not link stops connected by pathways
if (v instanceof TransitStopVertex && ((TransitStopVertex) v).hasPathways()) {
continue;
}
if (!link(v)) {
issueStore.add(unlinkedIssueMapper.apply(v));
}
// Keep lambda! A method-ref would cause incorrect class and line number to be logged
progress.step(m -> LOG.info(m));
}
LOG.info(progress.completeMessage());
}
use of org.opentripplanner.routing.vertextype.TransitStopVertex in project OpenTripPlanner by opentripplanner.
the class SimpleStreetSplitter method link.
/**
* split the edge and link in the transit stop
*/
private void link(Vertex tstop, StreetEdge edge, double xscale, RoutingRequest options) {
// TODO: we've already built this line string, we should save it
LineString orig = edge.getGeometry();
LineString transformed = equirectangularProject(orig, xscale);
LocationIndexedLine il = new LocationIndexedLine(transformed);
LinearLocation ll = il.project(new Coordinate(tstop.getLon() * xscale, tstop.getLat()));
// street to use the same vertices. Otherwise the order the stops are loaded in will affect where they are snapped.
if (ll.getSegmentIndex() == 0 && ll.getSegmentFraction() < 1e-8) {
makeLinkEdges(tstop, (StreetVertex) edge.getFromVertex());
} else // past the last point
if (ll.getSegmentIndex() == orig.getNumPoints() - 1) {
makeLinkEdges(tstop, (StreetVertex) edge.getToVertex());
} else // nPoints - 2: -1 to correct for index vs count, -1 to account for fencepost problem
if (ll.getSegmentIndex() == orig.getNumPoints() - 2 && ll.getSegmentFraction() > 1 - 1e-8) {
makeLinkEdges(tstop, (StreetVertex) edge.getToVertex());
} else {
TemporaryVertex temporaryVertex = null;
boolean endVertex = false;
if (tstop instanceof TemporaryVertex) {
temporaryVertex = (TemporaryVertex) tstop;
endVertex = temporaryVertex.isEndVertex();
}
// split the edge, get the split vertex
SplitterVertex v0 = split(edge, ll, temporaryVertex != null, endVertex);
makeLinkEdges(tstop, v0);
// edges that were missed by WalkableAreaBuilder
if (edge instanceof AreaEdge && tstop instanceof TransitStopVertex && this.addExtraEdgesToAreas) {
linkTransitToAreaVertices(v0, ((AreaEdge) edge).getArea());
}
}
}
use of org.opentripplanner.routing.vertextype.TransitStopVertex in project OpenTripPlanner by opentripplanner.
the class SimpleStreetSplitter method linkToStreetEdges.
public boolean linkToStreetEdges(Vertex vertex, TraverseMode traverseMode, RoutingRequest options, int radiusMeters) {
final double radiusDeg = SphericalDistanceLibrary.metersToDegrees(radiusMeters);
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 = new TraverseModeSet(traverseMode);
if (traverseMode == TraverseMode.BICYCLE) {
traverseModeSet.setWalk(true);
}
// Scope block to avoid confusing edge-related local variables with stop-related variables below.
{
// Perform several transformations at once on the edges returned by the index.
// Only consider street edges traversable by the given mode and still present in the graph.
// Calculate a distance to each of those edges, and keep only the ones within the search radius.
List<DistanceTo<StreetEdge>> candidateEdges = idx.query(env).stream().filter(StreetEdge.class::isInstance).map(StreetEdge.class::cast).filter(e -> e.canTraverse(traverseModeSet) && edgeReachableFromGraph(e)).map(e -> new DistanceTo<>(e, distance(vertex, e, xscale))).filter(ead -> ead.distanceDegreesLat < radiusDeg).collect(Collectors.toList());
// being non-deterministic.
if (!candidateEdges.isEmpty()) {
// There is at least one appropriate edge within range.
double closestDistance = candidateEdges.stream().mapToDouble(ce -> ce.distanceDegreesLat).min().getAsDouble();
candidateEdges.stream().filter(ce -> ce.distanceDegreesLat <= closestDistance + DUPLICATE_WAY_EPSILON_DEGREES).forEach(ce -> link(vertex, ce.item, xscale, options));
// Warn if a linkage was made for a transit stop, but the linkage was suspiciously long.
if (vertex instanceof TransitStopVertex) {
int distanceMeters = (int) SphericalDistanceLibrary.degreesLatitudeToMeters(closestDistance);
if (distanceMeters > WARNING_DISTANCE_METERS) {
issueStore.add(new StopLinkedTooFar((TransitStopVertex) vertex, distanceMeters));
}
}
return true;
}
}
if (radiusMeters >= MAX_SEARCH_RADIUS_METERS) {
// 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 {}, checking transit stop vertices.", vertex);
List<TransitStopVertex> transitStopVertices = transitStopIndex.query(env);
List<DistanceTo<TransitStopVertex>> candidateStops = transitStopVertices.stream().map(tsv -> new DistanceTo<>(tsv, distance(vertex, tsv, xscale))).filter(dts -> dts.distanceDegreesLat <= radiusDeg).collect(Collectors.toList());
if (candidateStops.isEmpty()) {
LOG.debug("No stops nearby.");
return false;
}
// There is at least one stop within range.
double closestDistance = candidateStops.stream().mapToDouble(c -> c.distanceDegreesLat).min().getAsDouble();
candidateStops.stream().filter(dts -> dts.distanceDegreesLat <= closestDistance + DUPLICATE_WAY_EPSILON_DEGREES).map(dts -> dts.item).forEach(sv -> {
LOG.debug("Linking vertex to stop: {}", sv.getName());
makeTemporaryEdges((TemporaryStreetLocation) vertex, sv);
});
return true;
}
return false;
}
Aggregations