use of org.opentripplanner.analyst.request.SampleGridRenderer.WTWD in project OpenTripPlanner by opentripplanner.
the class IsoChroneSPTRendererAccSampling method getIsochrones.
/**
* @param isoChroneRequest
* @param sptRequest
* @return
*/
@Override
public List<IsochroneData> getIsochrones(IsoChroneRequest isoChroneRequest, RoutingRequest sptRequest) {
final double offRoadDistanceMeters = isoChroneRequest.offRoadDistanceMeters;
// 1. Create a sample grid from the SPT, using the TimeGridRenderer
SampleGridRequest tgRequest = new SampleGridRequest();
tgRequest.maxTimeSec = isoChroneRequest.maxTimeSec;
tgRequest.precisionMeters = isoChroneRequest.precisionMeters;
tgRequest.offRoadDistanceMeters = isoChroneRequest.offRoadDistanceMeters;
tgRequest.coordinateOrigin = isoChroneRequest.coordinateOrigin;
ZSampleGrid<WTWD> sampleGrid = sampleGridRenderer.getSampleGrid(tgRequest, sptRequest);
// 2. Compute isolines
long t0 = System.currentTimeMillis();
ZMetric<WTWD> zMetric = new ZMetric<WTWD>() {
@Override
public int cut(WTWD zA, WTWD zB, WTWD z0) {
double t0 = z0.wTime / z0.w;
double tA = zA.d > z0.d ? Double.POSITIVE_INFINITY : zA.wTime / zA.w;
double tB = zB.d > z0.d ? Double.POSITIVE_INFINITY : zB.wTime / zB.w;
if (tA < t0 && t0 <= tB)
return 1;
if (tB < t0 && t0 <= tA)
return -1;
return 0;
}
@Override
public double interpolate(WTWD zA, WTWD zB, WTWD z0) {
if (zA.d > z0.d || zB.d > z0.d) {
if (zA.d > z0.d && zB.d > z0.d)
throw new AssertionError("dA > d0 && dB > d0");
// Interpolate on d
double k = zA.d == zB.d ? 0.5 : (z0.d - zA.d) / (zB.d - zA.d);
return k;
} else {
// Interpolate on t
double tA = zA.wTime / zA.w;
double tB = zB.wTime / zB.w;
double t0 = z0.wTime / z0.w;
double k = tA == tB ? 0.5 : (t0 - tA) / (tB - tA);
return k;
}
}
};
DelaunayIsolineBuilder<WTWD> isolineBuilder = new DelaunayIsolineBuilder<WTWD>(sampleGrid.delaunayTriangulate(), zMetric);
isolineBuilder.setDebug(isoChroneRequest.includeDebugGeometry);
List<IsochroneData> isochrones = new ArrayList<IsochroneData>();
for (Integer cutoffSec : isoChroneRequest.cutoffSecList) {
WTWD z0 = new WTWD();
z0.w = 1.0;
z0.wTime = cutoffSec;
z0.d = offRoadDistanceMeters;
IsochroneData isochrone = new IsochroneData(cutoffSec, isolineBuilder.computeIsoline(z0));
if (isoChroneRequest.includeDebugGeometry)
isochrone.debugGeometry = isolineBuilder.getDebugGeometry();
isochrones.add(isochrone);
}
long t1 = System.currentTimeMillis();
LOG.info("Computed {} isochrones in {}msec", isochrones.size(), (int) (t1 - t0));
return isochrones;
}
use of org.opentripplanner.analyst.request.SampleGridRenderer.WTWD in project OpenTripPlanner by opentripplanner.
the class TimeSurface method makeSampleGrid.
// TODO Lazy-initialize sample grid on demand so initial SPT finishes faster, and only isolines lag behind.
// however, the existing sampler needs an SPT, not general vertex-time mappings.
private void makeSampleGrid(ShortestPathTree spt) {
long t0 = System.currentTimeMillis();
// Todo: set dynamically and make sure this matches isoline builder params
final double gridSizeMeters = 300;
// off-road walk speed in m/sec
final double V0 = 1.00;
Coordinate coordinateOrigin = new Coordinate();
final double cosLat = FastMath.cos(toRadians(coordinateOrigin.y));
double dY = Math.toDegrees(gridSizeMeters / SphericalDistanceLibrary.RADIUS_OF_EARTH_IN_M);
double dX = dY / cosLat;
sampleGrid = new SparseMatrixZSampleGrid<WTWD>(16, spt.getVertexCount(), dX, dY, coordinateOrigin);
SampleGridRenderer.sampleSPT(spt, sampleGrid, gridSizeMeters * 0.7, gridSizeMeters, V0, spt.getOptions().getMaxWalkDistance(), Integer.MAX_VALUE, cosLat);
long t1 = System.currentTimeMillis();
LOG.info("Made SampleGrid from SPT in {} msec.", (int) (t1 - t0));
}
use of org.opentripplanner.analyst.request.SampleGridRenderer.WTWD in project OpenTripPlanner by opentripplanner.
the class IsochroneGenerator method getIsochronesAccumulative.
/**
* Make isochrones from a grid. This more general function should probably be reused by SurfaceResource.
* FIXME code duplication: function ripped off from SurfaceResource
* @param spacingMinutes the number of minutes between isochrones
* @return a list of evenly-spaced isochrones
*/
public static List<IsochroneData> getIsochronesAccumulative(ZSampleGrid<WTWD> grid, int spacingMinutes, int cutoffMinutes, int nMax) {
DelaunayIsolineBuilder<WTWD> isolineBuilder = new DelaunayIsolineBuilder<>(grid.delaunayTriangulate(), new WTWD.IsolineMetric());
List<IsochroneData> isochrones = new ArrayList<>();
for (int minutes = spacingMinutes, n = 0; minutes <= cutoffMinutes && n < nMax; minutes += spacingMinutes, n++) {
int seconds = minutes * 60;
SampleGridRenderer.WTWD z0 = new SampleGridRenderer.WTWD();
z0.w = 1.0;
z0.wTime = seconds;
z0.d = GRID_SIZE_METERS;
IsochroneData isochrone = new IsochroneData(seconds, isolineBuilder.computeIsoline(z0));
isochrones.add(isochrone);
if (n + 1 >= nMax) {
break;
}
}
return isochrones;
}
use of org.opentripplanner.analyst.request.SampleGridRenderer.WTWD in project OpenTripPlanner by opentripplanner.
the class IsochroneGenerator method makeGrid.
/**
* Make a ZSampleGrid from a PointSet and a parallel array of travel times for that PointSet.
* Those times could come from a ResultSetWithTimes or directly from a PropagatedTimesStore, which has one
* such array for each of min, avg, and max travel time over the departure time window it represents.
* If your PointSet is dense enough (e.g. every block in a city) then this should yield a decent surface and
* isochrones.
* FIXME code duplication, this is ripped off from TimeSurface and should probably replace the version there as it is more generic.
* @param walkSpeed the walk speed in meters per second
* @return a grid suitable for making isochrones, based on an arbitrary PointSet and times to reach all those points.
*/
public static ZSampleGrid makeGrid(PointSet pointSet, int[] times, double walkSpeed) {
// offroad walk distance roughly grid size
final double D0 = WALK_DISTANCE_GRID_SIZE_RATIO * GRID_SIZE_METERS;
// off-road walk speed in m/sec
final double V0 = walkSpeed;
// Use the first feature as the center of the projection
Coordinate coordinateOrigin = pointSet.getCoordinate(0);
final double cosLat = FastMath.cos(toRadians(coordinateOrigin.y));
double dY = Math.toDegrees(GRID_SIZE_METERS / SphericalDistanceLibrary.RADIUS_OF_EARTH_IN_M);
double dX = dY / cosLat;
ZSampleGrid grid = new SparseMatrixZSampleGrid<WTWD>(16, times.length, dX, dY, coordinateOrigin);
AccumulativeGridSampler.AccumulativeMetric<WTWD> metric = new SampleGridRenderer.WTWDAccumulativeMetric(cosLat, D0, V0, GRID_SIZE_METERS);
AccumulativeGridSampler<WTWD> sampler = new AccumulativeGridSampler<>(grid, metric);
// Iterate over every point in this PointSet, adding it to the ZSampleGrid
for (int p = 0; p < times.length; p++) {
int time = times[p];
WTWD z = new WTWD();
z.w = 1.0;
z.d = 0.0;
z.wTime = time;
// unused
z.wBoardings = 0;
// unused
z.wWalkDist = 0;
sampler.addSamplingPoint(pointSet.getCoordinate(p), z, V0);
}
sampler.close();
return grid;
}
use of org.opentripplanner.analyst.request.SampleGridRenderer.WTWD in project OpenTripPlanner by opentripplanner.
the class PropagatedTimesStore method makeSampleGridForVertices.
/**
* Create a SampleGrid from only the times stored in this PropagatedTimesStore.
* This assumes that the target indexes in this router/propagatedTimesStore are vertex indexes, not pointset indexes.
* This is not really ideal since it includes only intersection nodes, and no points along the road segments.
* FIXME this may be why we're getting hole-punching failures.
* TODO: rewrite the isoline code to use only primitive collections and operate on a scalar field.
*/
public SparseMatrixZSampleGrid<WTWD> makeSampleGridForVertices(int[] times, final double gridSizeMeters) {
SparseMatrixZSampleGrid<WTWD> grid;
long t0 = System.currentTimeMillis();
// Off-road max distance MUST be APPROX EQUALS to the grid precision
// TODO: Loosen this restriction (by adding more closing sample).
// Change the 0.8 magic factor here with caution. Should be roughly grid size.
final double offroadWalkDistance = 0.8 * gridSizeMeters;
// in m/sec
final double offroadWalkSpeed = 1.00;
Coordinate coordinateOrigin = graph.getCenter().get();
final double cosLat = FastMath.cos(toRadians(coordinateOrigin.y));
double dY = Math.toDegrees(gridSizeMeters / SphericalDistanceLibrary.RADIUS_OF_EARTH_IN_M);
double dX = dY / cosLat;
grid = new SparseMatrixZSampleGrid<WTWD>(16, times.length, dX, dY, coordinateOrigin);
AccumulativeGridSampler.AccumulativeMetric<SampleGridRenderer.WTWD> metric = new WTWDAccumulativeMetric(cosLat, offroadWalkDistance, offroadWalkSpeed, gridSizeMeters);
AccumulativeGridSampler<WTWD> sampler = new AccumulativeGridSampler<>(grid, metric);
// Iterate over every vertex, adding it to the ZSampleGrid if it was reached.
for (int v = 0; v < times.length; v++) {
int time = times[v];
if (time == Integer.MAX_VALUE) {
// MAX_VALUE is the "unreached" value
continue;
}
WTWD z = new WTWD();
z.w = 1.0;
z.d = 0.0;
z.wTime = time;
// unused
z.wBoardings = 0;
// unused
z.wWalkDist = 0;
// FIXME ack, this uses a hashtable and autoboxing!
Vertex vertex = graph.getVertexById(v);
// FIXME we should propagate along street geometries here
if (vertex != null) {
sampler.addSamplingPoint(vertex.getCoordinate(), z, offroadWalkSpeed);
}
}
sampler.close();
long t1 = System.currentTimeMillis();
LOG.info("Made scalar SampleGrid from TimeSurface in {} msec.", (int) (t1 - t0));
return grid;
}
Aggregations