use of org.opentripplanner.routing.edgetype.StreetEdge in project OpenTripPlanner by opentripplanner.
the class SampleGridRenderer method sampleSPT.
/**
* Sample a SPT using a SPTWalker and an AccumulativeGridSampler.
*/
public static void sampleSPT(final ShortestPathTree spt, ZSampleGrid<WTWD> sampleGrid, final double gridSizeMeters, final double offRoadDistanceMeters, final double offRoadWalkSpeedMps, final double maxWalkDistance, final int maxTimeSec, final double cosLat) {
AccumulativeMetric<WTWD> accMetric = new WTWDAccumulativeMetric(cosLat, offRoadDistanceMeters, offRoadWalkSpeedMps, gridSizeMeters);
final AccumulativeGridSampler<WTWD> gridSampler = new AccumulativeGridSampler<WTWD>(sampleGrid, accMetric);
// At which distance we split edges along the geometry during sampling.
// For best results, this should be slighly lower than the grid size.
double walkerSplitDistanceMeters = gridSizeMeters * 0.5;
SPTWalker johnny = new SPTWalker(spt);
johnny.walk(new SPTVisitor() {
@Override
public final boolean accept(Edge e) {
return e instanceof StreetEdge;
}
@Override
public final void visit(Edge e, Coordinate c, State s0, State s1, double d0, double d1, double speedAlongEdge) {
double wd0 = s0.getWalkDistance() + d0;
double wd1 = s0.getWalkDistance() + d1;
double t0 = wd0 > maxWalkDistance ? Double.POSITIVE_INFINITY : s0.getActiveTime() + d0 / speedAlongEdge;
double t1 = wd1 > maxWalkDistance ? Double.POSITIVE_INFINITY : s1.getActiveTime() + d1 / speedAlongEdge;
if (t0 < maxTimeSec || t1 < maxTimeSec) {
if (!Double.isInfinite(t0) || !Double.isInfinite(t1)) {
WTWD z = new WTWD();
z.w = 1.0;
z.d = 0.0;
if (t0 < t1) {
z.wTime = t0;
z.wBoardings = s0.getNumBoardings();
z.wWalkDist = s0.getWalkDistance() + d0;
} else {
z.wTime = t1;
z.wBoardings = s1.getNumBoardings();
z.wWalkDist = s1.getWalkDistance() + d1;
}
gridSampler.addSamplingPoint(c, z, offRoadWalkSpeedMps);
}
}
}
}, walkerSplitDistanceMeters);
gridSampler.close();
}
use of org.opentripplanner.routing.edgetype.StreetEdge 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.edgetype.StreetEdge in project OpenTripPlanner by opentripplanner.
the class ElevationModule method buildGraph.
@Override
public void buildGraph(Graph graph, HashMap<Class<?>, Object> extra) {
gridCoverageFactory.setGraph(graph);
Coverage gridCov = gridCoverageFactory.getGridCoverage();
// If gridCov is a GridCoverage2D, apply a bilinear interpolator. Otherwise, just use the
// coverage as is (note: UnifiedGridCoverages created by NEDGridCoverageFactoryImpl handle
// interpolation internally)
coverage = (gridCov instanceof GridCoverage2D) ? Interpolator2D.create((GridCoverage2D) gridCov, new InterpolationBilinear()) : gridCov;
log.info("Setting street elevation profiles from digital elevation model...");
List<StreetEdge> edgesWithElevation = new ArrayList<StreetEdge>();
int nProcessed = 0;
int nTotal = graph.countEdges();
for (Vertex gv : graph.getVertices()) {
for (Edge ee : gv.getOutgoing()) {
if (ee instanceof StreetWithElevationEdge) {
StreetWithElevationEdge edgeWithElevation = (StreetWithElevationEdge) ee;
processEdge(graph, edgeWithElevation);
if (edgeWithElevation.getElevationProfile() != null && !edgeWithElevation.isElevationFlattened()) {
edgesWithElevation.add(edgeWithElevation);
}
nProcessed += 1;
if (nProcessed % 50000 == 0) {
log.info("set elevation on {}/{} edges", nProcessed, nTotal);
double failurePercentage = nPointsOutsideDEM / nPointsEvaluated * 100;
if (failurePercentage > 50) {
log.warn("Fetching elevation failed at {}/{} points ({}%)", nPointsOutsideDEM, nPointsEvaluated, failurePercentage);
log.warn("Elevation is missing at a large number of points. DEM may be for the wrong region. " + "If it is unprojected, perhaps the axes are not in (longitude, latitude) order.");
}
}
}
}
}
@SuppressWarnings("unchecked") HashMap<Vertex, Double> extraElevation = (HashMap<Vertex, Double>) extra.get(ElevationPoint.class);
assignMissingElevations(graph, edgesWithElevation, extraElevation);
}
use of org.opentripplanner.routing.edgetype.StreetEdge in project OpenTripPlanner by opentripplanner.
the class PortlandCustomNamer method nameAccordingToDestination.
private String nameAccordingToDestination(Graph graph, StreetEdge e, int maxDepth) {
if (maxDepth == 0) {
return null;
}
Vertex toVertex = e.getToVertex();
for (StreetEdge out : Iterables.filter(toVertex.getOutgoing(), StreetEdge.class)) {
if (out.hasBogusName()) {
String name = nameAccordingToDestination(graph, out, maxDepth - 1);
if (name == null) {
continue;
}
e.setName(new NonLocalizedString(name));
return name;
} else {
String name = out.getName();
e.setName(new NonLocalizedString(name));
return name;
}
}
return null;
}
use of org.opentripplanner.routing.edgetype.StreetEdge in project OpenTripPlanner by opentripplanner.
the class PortlandCustomNamer method nameAccordingToOrigin.
private String nameAccordingToOrigin(Graph graph, StreetEdge e, int maxDepth) {
if (maxDepth == 0) {
return null;
}
Vertex fromVertex = e.getFromVertex();
for (StreetEdge in : Iterables.filter(fromVertex.getIncoming(), StreetEdge.class)) {
if (in.hasBogusName()) {
String name = nameAccordingToOrigin(graph, in, maxDepth - 1);
if (name == null) {
continue;
}
e.setName(new NonLocalizedString(name));
return name;
} else {
String name = in.getName();
e.setName(new NonLocalizedString(name));
return name;
}
}
return null;
}
Aggregations