Search in sources :

Example 1 with WTWD

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;
}
Also used : WTWD(org.opentripplanner.analyst.request.SampleGridRenderer.WTWD) DelaunayIsolineBuilder(org.opentripplanner.common.geometry.DelaunayIsolineBuilder) ArrayList(java.util.ArrayList) IsochroneData(org.opentripplanner.analyst.core.IsochroneData) ZMetric(org.opentripplanner.common.geometry.IsolineBuilder.ZMetric)

Example 2 with WTWD

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));
}
Also used : WTWD(org.opentripplanner.analyst.request.SampleGridRenderer.WTWD) Coordinate(com.vividsolutions.jts.geom.Coordinate)

Example 3 with WTWD

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;
}
Also used : WTWD(org.opentripplanner.analyst.request.SampleGridRenderer.WTWD) DelaunayIsolineBuilder(org.opentripplanner.common.geometry.DelaunayIsolineBuilder) ArrayList(java.util.ArrayList) SampleGridRenderer(org.opentripplanner.analyst.request.SampleGridRenderer) IsochroneData(org.opentripplanner.analyst.core.IsochroneData) WTWD(org.opentripplanner.analyst.request.SampleGridRenderer.WTWD)

Example 4 with WTWD

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;
}
Also used : SparseMatrixZSampleGrid(org.opentripplanner.common.geometry.SparseMatrixZSampleGrid) ZSampleGrid(org.opentripplanner.common.geometry.ZSampleGrid) WTWD(org.opentripplanner.analyst.request.SampleGridRenderer.WTWD) Coordinate(com.vividsolutions.jts.geom.Coordinate) AccumulativeGridSampler(org.opentripplanner.common.geometry.AccumulativeGridSampler) SparseMatrixZSampleGrid(org.opentripplanner.common.geometry.SparseMatrixZSampleGrid)

Example 5 with WTWD

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;
}
Also used : WTWDAccumulativeMetric(org.opentripplanner.analyst.request.SampleGridRenderer.WTWDAccumulativeMetric) Vertex(org.opentripplanner.routing.graph.Vertex) WTWD(org.opentripplanner.analyst.request.SampleGridRenderer.WTWD) Coordinate(com.vividsolutions.jts.geom.Coordinate) AccumulativeGridSampler(org.opentripplanner.common.geometry.AccumulativeGridSampler)

Aggregations

WTWD (org.opentripplanner.analyst.request.SampleGridRenderer.WTWD)11 Coordinate (com.vividsolutions.jts.geom.Coordinate)5 ArrayList (java.util.ArrayList)5 IsochroneData (org.opentripplanner.analyst.core.IsochroneData)5 DelaunayIsolineBuilder (org.opentripplanner.common.geometry.DelaunayIsolineBuilder)5 AccumulativeGridSampler (org.opentripplanner.common.geometry.AccumulativeGridSampler)4 Vertex (org.opentripplanner.routing.graph.Vertex)3 TIntArrayList (gnu.trove.list.array.TIntArrayList)2 ResultSet (org.opentripplanner.analyst.ResultSet)2 WTWDAccumulativeMetric (org.opentripplanner.analyst.request.SampleGridRenderer.WTWDAccumulativeMetric)2 ImageInfo (ar.com.hjg.pngj.ImageInfo)1 ImageLineInt (ar.com.hjg.pngj.ImageLineInt)1 PngWriter (ar.com.hjg.pngj.PngWriter)1 PngChunkTEXT (ar.com.hjg.pngj.chunks.PngChunkTEXT)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 Date (java.util.Date)1 CacheControl (javax.ws.rs.core.CacheControl)1 SampleGridRenderer (org.opentripplanner.analyst.request.SampleGridRenderer)1 SampleGridRequest (org.opentripplanner.analyst.request.SampleGridRequest)1 ZMetric (org.opentripplanner.common.geometry.IsolineBuilder.ZMetric)1