use of org.opentripplanner.analyst.core.IsochroneData 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.core.IsochroneData in project OpenTripPlanner by opentripplanner.
the class LIsochrone method makeContourFeatures.
/**
* Create a geotools feature collection from a list of isochrones in the OTPA internal format.
* Once in a FeatureCollection, they can for example be exported as GeoJSON.
*/
public static SimpleFeatureCollection makeContourFeatures(List<IsochroneData> isochrones) {
DefaultFeatureCollection featureCollection = new DefaultFeatureCollection(null, contourSchema);
SimpleFeatureBuilder fbuilder = new SimpleFeatureBuilder(contourSchema);
for (IsochroneData isochrone : isochrones) {
fbuilder.add(isochrone.geometry);
fbuilder.add(isochrone.cutoffSec);
featureCollection.add(fbuilder.buildFeature(null));
}
return featureCollection;
}
use of org.opentripplanner.analyst.core.IsochroneData 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.core.IsochroneData in project OpenTripPlanner by opentripplanner.
the class TNPropagatedTimesStore method makeIsochroneForVertices.
/**
* This bypasses a bunch of TimeSurface conversion/copy steps we were going though and makes the isochrones directly.
* This assumes that the target indexes in this router/propagatedTimesStore are vertex indexes, not pointset indexes.
* Called three times on min/avg/max to create the three elements of a ResultEnvelope.
*/
private ResultSet makeIsochroneForVertices(int[] times) {
final int spacing = 5;
final int nMax = 24;
final int cutoffMinutes = 120;
final int offroadDistanceMeters = 250;
SparseMatrixZSampleGrid<WTWD> grid = makeSampleGridForVertices(times, offroadDistanceMeters);
long t0 = System.currentTimeMillis();
DelaunayIsolineBuilder<WTWD> isolineBuilder = new DelaunayIsolineBuilder<>(grid.delaunayTriangulate(), new WTWD.IsolineMetric());
List<IsochroneData> isoData = new ArrayList<IsochroneData>();
for (int minutes = spacing, n = 0; minutes <= cutoffMinutes && n < nMax; minutes += spacing, n++) {
int seconds = minutes * 60;
WTWD z0 = new WTWD();
z0.w = 1.0;
z0.wTime = seconds;
z0.d = offroadDistanceMeters;
IsochroneData isochrone = new IsochroneData(seconds, isolineBuilder.computeIsoline(z0));
isoData.add(isochrone);
}
long t1 = System.currentTimeMillis();
ResultSet resultSet = new ResultSet();
resultSet.isochrones = new IsochroneData[isoData.size()];
isoData.toArray(resultSet.isochrones);
LOG.debug("Computed {} isochrones in {} msec", isoData.size(), (int) (t1 - t0));
return resultSet;
}
use of org.opentripplanner.analyst.core.IsochroneData in project OpenTripPlanner by opentripplanner.
the class SurfaceResource method getIsochronesAccumulative.
/**
* Use Laurent's accumulative grid sampler. Cutoffs in minutes.
* The grid and Delaunay triangulation are cached, so subsequent requests are very fast.
*
* @param spacing the number of minutes between isochrones
* @return a list of evenly-spaced isochrones up to the timesurface's cutoff point
*/
public static List<IsochroneData> getIsochronesAccumulative(TimeSurface surf, int spacing, int nMax) {
long t0 = System.currentTimeMillis();
if (surf.sampleGrid == null) {
// The sample grid was not built from the SPT; make a minimal one including only time from the vertices in this timesurface
surf.makeSampleGridWithoutSPT();
}
DelaunayIsolineBuilder<WTWD> isolineBuilder = new DelaunayIsolineBuilder<WTWD>(surf.sampleGrid.delaunayTriangulate(), new WTWD.IsolineMetric());
List<IsochroneData> isochrones = new ArrayList<IsochroneData>();
for (int minutes = spacing, n = 0; minutes <= surf.cutoffMinutes && n < nMax; minutes += spacing, n++) {
int seconds = minutes * 60;
WTWD z0 = new WTWD();
z0.w = 1.0;
z0.wTime = seconds;
// meters. TODO set dynamically / properly, make sure it matches grid cell size?
z0.d = 300;
IsochroneData isochrone = new IsochroneData(seconds, isolineBuilder.computeIsoline(z0));
isochrones.add(isochrone);
}
long t1 = System.currentTimeMillis();
LOG.debug("Computed {} isochrones in {} msec", isochrones.size(), (int) (t1 - t0));
return isochrones;
}
Aggregations