use of org.opentripplanner.analyst.core.Sample in project OpenTripPlanner by opentripplanner.
the class ResultSet method forTravelTimes.
public static ResultSet forTravelTimes(Population population, ShortestPathTree spt) {
double[] results = new double[population.size()];
int i = 0;
for (Individual indiv : population) {
Sample s = indiv.sample;
long t = Long.MAX_VALUE;
if (s == null)
t = -2;
else
t = s.eval(spt);
if (t == Long.MAX_VALUE)
t = -1;
results[i] = t;
i++;
}
return new ResultSet(population, results);
}
use of org.opentripplanner.analyst.core.Sample in project OpenTripPlanner by opentripplanner.
the class StreetVertexIndexServiceImpl method getSampleVertexAt.
@Override
public Vertex getSampleVertexAt(Coordinate coordinate, boolean dest) {
SampleFactory sfac = graph.getSampleFactory();
Sample s = sfac.getSample(coordinate.x, coordinate.y);
if (s == null)
return null;
// create temp vertex
SampleVertex v = new SampleVertex(graph, coordinate);
// create edges
if (dest) {
if (s.v0 != null)
new SampleEdge(s.v0, v, s.d0);
if (s.v1 != null)
new SampleEdge(s.v1, v, s.d1);
} else {
if (s.v0 != null)
new SampleEdge(v, s.v0, s.d0);
if (s.v1 != null)
new SampleEdge(v, s.v1, s.d1);
}
return v;
}
use of org.opentripplanner.analyst.core.Sample in project OpenTripPlanner by opentripplanner.
the class SampleStopLinker method link.
/**
* Link all transit stops. If makeTransfers is true, create direct transfer
* edges between stops linked to the same pair of vertices. This is important
* e.g. for transit centers where there are many stops on the same street segment;
* we don't want to force the user to walk to the end of the street and back.
*
* If you're not generating transfers via the street network there is no need to make
* transfers at this stage. But if you're not generating transfers via the street network,
* why are you using this module at all?
*/
public void link(boolean makeTransfers) {
if (makeTransfers)
links = HashMultimap.create();
SampleFactory sf = graph.getSampleFactory();
for (TransitStop tstop : Iterables.filter(graph.getVertices(), TransitStop.class)) {
Sample s = sf.getSample(tstop.getLon(), tstop.getLat());
// TODO: stop unlinked annotation
if (s == null)
continue;
new IntersectionTransitLink(tstop, (OsmVertex) s.v0, s.d0);
new IntersectionTransitLink((OsmVertex) s.v0, tstop, s.d0);
new IntersectionTransitLink(tstop, (OsmVertex) s.v1, s.d1);
new IntersectionTransitLink((OsmVertex) s.v1, tstop, s.d1);
if (makeTransfers) {
// save the sample so we can make direct transfers between stops
VertexPair vp = new VertexPair(s.v0, s.v1);
links.put(vp, tstop);
}
}
if (makeTransfers) {
// make direct transfers between stops
for (Collection<TransitStop> tss : links.asMap().values()) {
for (TransitStop ts0 : tss) {
for (TransitStop ts1 : tss) {
// make a geometry
GeometryFactory gf = GeometryUtils.getGeometryFactory();
LineString geom = gf.createLineString(new Coordinate[] { ts0.getCoordinate(), ts1.getCoordinate() });
double dist = SphericalDistanceLibrary.distance(ts0.getLat(), ts0.getLon(), ts1.getLat(), ts1.getLon());
// building unidirectional edge, we'll hit this again in the opposite direction
new SimpleTransfer(ts1, ts1, dist, geom);
}
}
}
}
}
use of org.opentripplanner.analyst.core.Sample in project OpenTripPlanner by opentripplanner.
the class IsoChroneSPTRendererRecursiveGrid method getIsochrones.
/**
* @param isoChroneRequest
* @param sptRequest
* @return
*/
@Override
public List<IsochroneData> getIsochrones(IsoChroneRequest isoChroneRequest, RoutingRequest sptRequest) {
if (sptRequest.routerId != null && !sptRequest.routerId.isEmpty())
throw new IllegalArgumentException("TODO: SampleSource is not multi-router compatible (yet).");
// 1. Compute the Shortest Path Tree.
long t0 = System.currentTimeMillis();
sptRequest.worstTime = (sptRequest.dateTime + (sptRequest.arriveBy ? -isoChroneRequest.maxCutoffSec : isoChroneRequest.maxCutoffSec));
sptRequest.batch = true;
sptRequest.setRoutingContext(graph);
// TODO handle different path dominance conditions
final ShortestPathTree spt = new AStar().getShortestPathTree(sptRequest);
sptRequest.cleanup();
// 2. Compute the set of initial points
long t1 = System.currentTimeMillis();
List<Coordinate> initialPoints = computeInitialPoints(spt);
// 3. Compute the isochrone based on the SPT.
ZFunc timeFunc = new ZFunc() {
@Override
public long z(Coordinate c) {
Sample sample = sampleSource.getSample(c.x, c.y);
if (sample == null) {
return Long.MAX_VALUE;
}
Long z = sample.eval(spt);
return z;
}
};
// TODO Snap the center as XYZ tile grid for better sample-reuse (if using sample cache).
Coordinate center = sptRequest.from.getCoordinate();
double gridSizeMeters = isoChroneRequest.precisionMeters;
double dY = Math.toDegrees(gridSizeMeters / SphericalDistanceLibrary.RADIUS_OF_EARTH_IN_M);
double dX = dY / Math.cos(Math.toRadians(center.x));
LOG.info("dX={}, dY={}", dX, dY);
RecursiveGridIsolineBuilder isolineBuilder = new RecursiveGridIsolineBuilder(dX, dY, center, timeFunc, initialPoints);
isolineBuilder.setDebugCrossingEdges(isoChroneRequest.includeDebugGeometry);
isolineBuilder.setDebugSeedGrid(isoChroneRequest.includeDebugGeometry);
List<IsochroneData> isochrones = new ArrayList<IsochroneData>();
for (Integer cutoffSec : isoChroneRequest.cutoffSecList) {
IsochroneData isochrone = new IsochroneData(cutoffSec, isolineBuilder.computeIsoline(cutoffSec));
if (isoChroneRequest.includeDebugGeometry)
isochrone.debugGeometry = isolineBuilder.getDebugGeometry();
isochrones.add(isochrone);
}
long t2 = System.currentTimeMillis();
LOG.info("Computed SPT in {}msec, {} isochrones in {}msec", (int) (t1 - t0), isochrones.size(), (int) (t2 - t1));
return isochrones;
}
use of org.opentripplanner.analyst.core.Sample in project OpenTripPlanner by opentripplanner.
the class SampleFactory method getSample.
@Override
public /**
* implements SampleSource interface
*/
Sample getSample(double lon, double lat) {
Coordinate c = new Coordinate(lon, lat);
// query always returns a (possibly empty) list, but never null
Envelope env = new Envelope(c);
// find scaling factor for equirectangular projection
double xscale = Math.cos(c.y * Math.PI / 180);
env.expandBy(searchRadiusLat / xscale, searchRadiusLat);
@SuppressWarnings("unchecked") Collection<Vertex> vertices = graph.streetIndex.getVerticesForEnvelope(env);
// make sure things are in the radius
final TIntDoubleMap distances = new TIntDoubleHashMap();
for (Vertex v : vertices) {
if (!(v instanceof OsmVertex))
continue;
// figure ersatz distance
double dx = (lon - v.getLon()) * xscale;
double dy = lat - v.getLat();
distances.put(v.getIndex(), dx * dx + dy * dy);
}
List<Vertex> sorted = new ArrayList<Vertex>();
for (Vertex input : vertices) {
if (!(input instanceof OsmVertex && distances.get(input.getIndex()) < searchRadiusLat * searchRadiusLat))
continue;
for (StreetEdge e : Iterables.filter(input.getOutgoing(), StreetEdge.class)) {
if (e.canTraverse(new TraverseModeSet(TraverseMode.WALK))) {
sorted.add(input);
break;
}
}
}
// sort list by distance
Collections.sort(sorted, new Comparator<Vertex>() {
@Override
public int compare(Vertex o1, Vertex o2) {
double d1 = distances.get(o1.getIndex());
double d2 = distances.get(o2.getIndex());
if (d1 < d2)
return -1;
else if (d1 > d2)
return 1;
else
return 0;
}
});
Vertex v0, v1;
if (sorted.isEmpty())
return null;
else if (sorted.size() <= 2) {
v0 = sorted.get(0);
v1 = sorted.size() > 1 ? sorted.get(1) : null;
} else {
int vxi = 0;
// Group them by distance
Vertex[] vx = new Vertex[2];
ArrayList<Vertex> grouped = new ArrayList<>();
// of at least EPSILON. Once we've done that, break ties using labels (which are OSM IDs).
for (int i = 0; i < sorted.size(); i++) {
if (vxi >= 2)
break;
if (grouped.isEmpty()) {
grouped.add(sorted.get(i));
continue;
}
double dlast = distances.get(sorted.get(i - 1).getIndex());
double dthis = distances.get(sorted.get(i).getIndex());
if (dthis - dlast < EPSILON) {
grouped.add(sorted.get(i));
continue;
} else {
// we have a distinct group of vertices
// sort them by OSM IDs
// this seems like it would be slow but keep in mind that it will only do any work
// when there are multiple members of a group, which is relatively rare.
Collections.sort(grouped, (vv1, vv2) -> vv1.getLabel().compareTo(vv2.getLabel()));
// then loop over the list until it's empty or we've found two vertices
int gi = 0;
while (vxi < 2 && gi < grouped.size()) {
vx[vxi++] = grouped.get(gi++);
}
// get ready for the next group
grouped.clear();
}
}
v0 = vx[0];
v1 = vx[1];
}
double d0 = v0 != null ? SphericalDistanceLibrary.distance(v0.getLat(), v0.getLon(), lat, lon) : 0;
double d1 = v1 != null ? SphericalDistanceLibrary.distance(v1.getLat(), v1.getLon(), lat, lon) : 0;
return new Sample(v0, (int) d0, v1, (int) d1);
}
Aggregations