
org.opentripplanner.analyst.request.IsoChroneSPTRendererRecursiveGrid Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
/* This program is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
package org.opentripplanner.analyst.request;
import java.util.ArrayList;
import java.util.List;
import org.opentripplanner.analyst.core.IsochroneData;
import org.opentripplanner.analyst.core.Sample;
import org.opentripplanner.analyst.core.SampleSource;
import org.opentripplanner.common.geometry.RecursiveGridIsolineBuilder;
import org.opentripplanner.common.geometry.RecursiveGridIsolineBuilder.ZFunc;
import org.opentripplanner.common.geometry.SphericalDistanceLibrary;
import org.opentripplanner.routing.algorithm.AStar;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.graph.Vertex;
import org.opentripplanner.routing.spt.ShortestPathTree;
import org.opentripplanner.routing.vertextype.StreetVertex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vividsolutions.jts.geom.Coordinate;
/**
* Compute isochrones out of a shortest path tree request (RecursiveGrid isoline algorithm).
*
* @author laurent
*/
public class IsoChroneSPTRendererRecursiveGrid implements IsoChroneSPTRenderer {
private static final Logger LOG = LoggerFactory
.getLogger(IsoChroneSPTRendererRecursiveGrid.class);
private Graph graph;
private SampleSource sampleSource;
public IsoChroneSPTRendererRecursiveGrid(Graph graph) {
this.graph = graph;
this.sampleSource = graph.getSampleFactory();
}
/**
* @param isoChroneRequest
* @param sptRequest
* @return
*/
@Override
public List 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 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 isochrones = new ArrayList();
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;
}
/**
* Compute a set of initial coordinates for the given SPT
*
* @param spt
* @return
*/
private List computeInitialPoints(ShortestPathTree spt) {
List retval = new ArrayList(spt.getVertexCount());
for (State s : spt.getAllStates()) {
Vertex v = s.getVertex();
// Take only street
if (v instanceof StreetVertex) {
retval.add(v.getCoordinate());
}
}
LOG.debug("Created {} initial points from {} vertexes.", retval.size(),
spt.getVertexCount());
return retval;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy