Skip to content

Commit

Permalink
Remove SPTService interface #1725
Browse files Browse the repository at this point in the history
GenericAStar is the only way we really do searches.
There are some earliest arrival searches but those should just use a different SPT
implementation.
  • Loading branch information
abyrd committed Feb 2, 2015
1 parent cf8bbcb commit 6d40355
Show file tree
Hide file tree
Showing 12 changed files with 29 additions and 176 deletions.
Expand Up @@ -27,10 +27,10 @@ the License, or (at your option) any later version.
import org.opentripplanner.analyst.core.Sample;
import org.opentripplanner.analyst.request.SampleFactory;
import org.opentripplanner.common.model.GenericLocation;
import org.opentripplanner.routing.algorithm.GenericAStar;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.error.VertexNotFoundException;
import org.opentripplanner.routing.services.GraphService;
import org.opentripplanner.routing.services.SPTService;
import org.opentripplanner.routing.spt.ShortestPathTree;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -41,7 +41,6 @@ public class BatchProcessor {
private static final String EXAMPLE_CONTEXT = "batch-context.xml";

private GraphService graphService;
private SPTService sptService;
private SampleFactory sampleFactory;

private Population origins;
Expand Down Expand Up @@ -249,7 +248,7 @@ public void run() {
LOG.debug("calling origin : {}", oi);
RoutingRequest req = buildRequest(oi);
if (req != null) {
ShortestPathTree spt = sptService.getShortestPathTree(req);
ShortestPathTree spt = new GenericAStar().getShortestPathTree(req);
// ResultSet should be a local to avoid memory leak
ResultSet results = ResultSet.forTravelTimes(destinations, spt);
req.cleanup();
Expand Down
Expand Up @@ -22,11 +22,11 @@ the License, or (at your option) any later version.
import org.opentripplanner.common.geometry.RecursiveGridIsolineBuilder;
import org.opentripplanner.common.geometry.RecursiveGridIsolineBuilder.ZFunc;
import org.opentripplanner.common.geometry.SphericalDistanceLibrary;
import org.opentripplanner.routing.algorithm.GenericAStar;
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.services.SPTService;
import org.opentripplanner.routing.spt.ShortestPathTree;
import org.opentripplanner.routing.vertextype.StreetVertex;
import org.slf4j.Logger;
Expand All @@ -45,12 +45,10 @@ public class IsoChroneSPTRendererRecursiveGrid implements IsoChroneSPTRenderer {
.getLogger(IsoChroneSPTRendererRecursiveGrid.class);

private Graph graph;
private SPTService sptService;
private SampleSource sampleSource;

public IsoChroneSPTRendererRecursiveGrid(Graph graph, SPTService sptService) {
public IsoChroneSPTRendererRecursiveGrid(Graph graph) {
this.graph = graph;
this.sptService = sptService;
this.sampleSource = graph.getSampleFactory();
}

Expand All @@ -73,7 +71,8 @@ public List<IsochroneData> getIsochrones(IsoChroneRequest isoChroneRequest,
+ (sptRequest.arriveBy ? -isoChroneRequest.maxCutoffSec : isoChroneRequest.maxCutoffSec));
sptRequest.batch = true;
sptRequest.setRoutingContext(graph);
final ShortestPathTree spt = sptService.getShortestPathTree(sptRequest);
// TODO handle different path dominance conditions
final ShortestPathTree spt = new GenericAStar().getShortestPathTree(sptRequest);
sptRequest.cleanup();

// 2. Compute the set of initial points
Expand Down
Expand Up @@ -51,13 +51,12 @@ the License, or (at your option) any later version.
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opentripplanner.api.common.RoutingResource;
import org.opentripplanner.routing.algorithm.EarliestArrivalSPTService;
import org.opentripplanner.routing.algorithm.EarliestArrivalSearch;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.edgetype.StreetTransitLink;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.graph.Vertex;
import org.opentripplanner.routing.services.SPTService;
import org.opentripplanner.routing.spt.ShortestPathTree;
import org.opentripplanner.routing.vertextype.IntersectionVertex;
import org.opentripplanner.routing.vertextype.StreetVertex;
Expand Down Expand Up @@ -96,7 +95,7 @@ public class SimpleIsochrone extends RoutingResource {

private static final Logger LOG = LoggerFactory.getLogger(SimpleIsochrone.class);

private static final SPTService sptService = new EarliestArrivalSPTService();
private static final EarliestArrivalSearch sptService = new EarliestArrivalSearch();

/* Parameters shared between all methods. */
@QueryParam("requestSpacingMinutes") @DefaultValue("30")
Expand Down
@@ -1,57 +1,28 @@
package org.opentripplanner.api.resource;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;

import org.apache.commons.math3.util.FastMath;
import org.geotools.feature.FeatureCollection;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.geometry.Envelope2D;
import org.opentripplanner.analyst.ResultSet;
import org.opentripplanner.analyst.PointSet;
import org.opentripplanner.analyst.SampleSet;
import org.opentripplanner.analyst.TimeSurface;
import org.opentripplanner.analyst.core.IsochroneData;
import org.opentripplanner.analyst.core.Sample;
import org.opentripplanner.analyst.core.SlippyTile;
import org.opentripplanner.analyst.request.IsoChroneRequest;
import org.opentripplanner.analyst.request.RenderRequest;
import org.opentripplanner.analyst.request.Renderer;
import org.opentripplanner.analyst.request.SampleGridRenderer;
import org.opentripplanner.analyst.request.SampleGridRequest;
import org.opentripplanner.analyst.request.TileRequest;
import org.opentripplanner.api.common.ParameterException;
import org.opentripplanner.api.common.RoutingResource;
import org.opentripplanner.api.model.TimeSurfaceShort;
import org.opentripplanner.api.parameter.Layer;
import org.opentripplanner.api.parameter.LayerList;
import org.opentripplanner.api.parameter.MIMEImageFormat;
import org.opentripplanner.api.parameter.Style;
import org.opentripplanner.api.parameter.StyleList;
import org.opentripplanner.common.geometry.AccumulativeGridSampler;
import org.opentripplanner.common.geometry.DelaunayIsolineBuilder;
import org.opentripplanner.common.geometry.DistanceLibrary;
import org.opentripplanner.common.geometry.IsolineBuilder;
import org.opentripplanner.common.geometry.RecursiveGridIsolineBuilder;
import org.opentripplanner.common.geometry.SparseMatrixZSampleGrid;
import org.opentripplanner.common.geometry.ZSampleGrid;
import org.opentripplanner.routing.algorithm.EarliestArrivalSPTService;
import org.opentripplanner.routing.algorithm.GenericAStar;
import org.opentripplanner.routing.algorithm.EarliestArrivalSearch;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.edgetype.StreetEdge;
import org.opentripplanner.routing.graph.Edge;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.graph.Vertex;
import org.opentripplanner.routing.services.SPTService;
import org.opentripplanner.routing.spt.SPTWalker;
import org.opentripplanner.routing.spt.ShortestPathTree;
import org.opentripplanner.routing.vertextype.StreetVertex;
import org.opentripplanner.standalone.OTPServer;
import org.opentripplanner.standalone.Router;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -60,7 +31,6 @@
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
Expand All @@ -74,13 +44,10 @@

import java.io.IOException;
import java.io.OutputStream;
import java.sql.Time;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static org.apache.commons.math3.util.FastMath.toRadians;

@Path("/surfaces")
@Produces({ MediaType.APPLICATION_JSON })
public class SurfaceResource extends RoutingResource {
Expand All @@ -103,7 +70,7 @@ public Response createSurface(@QueryParam("cutoffMinutes")
Router router = otpServer.getRouter(routerId);
req.setRoutingContext(router.graph);

EarliestArrivalSPTService sptService = new EarliestArrivalSPTService();
EarliestArrivalSearch sptService = new EarliestArrivalSearch();
sptService.maxDuration = (60 * cutoffMinutes);
ShortestPathTree spt = sptService.getShortestPathTree(req);
req.cleanup();
Expand Down
Expand Up @@ -11,7 +11,7 @@
import org.opentripplanner.common.geometry.GeometryUtils;
import org.opentripplanner.common.geometry.PackedCoordinateSequence;
import org.opentripplanner.common.geometry.SphericalDistanceLibrary;
import org.opentripplanner.routing.algorithm.EarliestArrivalSPTService;
import org.opentripplanner.routing.algorithm.EarliestArrivalSearch;
import org.opentripplanner.routing.automata.DFA;
import org.opentripplanner.routing.automata.Nonterminal;
import org.opentripplanner.routing.core.RoutingRequest;
Expand Down Expand Up @@ -54,7 +54,7 @@ public class NearbyStopFinder {

/* Fields used when finding stops via the street network. */
private PathParser parsers[];
private EarliestArrivalSPTService earliestArrivalSPTService;
private EarliestArrivalSearch earliestArrivalSearch;

/* Fields used when finding stops without a street network. */
private StreetVertexIndexService streetIndex;
Expand All @@ -78,8 +78,8 @@ public NearbyStopFinder(Graph graph, double radius, boolean useStreets) {
this.radius = radius;
if (useStreets) {
parsers = new PathParser[] {new TransferFinderParser()};
earliestArrivalSPTService = new EarliestArrivalSPTService();
earliestArrivalSPTService.maxDuration = (int) radius; // FIXME assuming 1 m/sec, use hard distance limiting to match straight-line mode
earliestArrivalSearch = new EarliestArrivalSearch();
earliestArrivalSearch.maxDuration = (int) radius; // FIXME assuming 1 m/sec, use hard distance limiting to match straight-line mode
} else {
streetIndex = new StreetVertexIndexServiceImpl(graph); // FIXME use the one already in the graph if it exists
distanceLibrary = SphericalDistanceLibrary.getInstance();
Expand Down Expand Up @@ -139,7 +139,7 @@ public List<StopAtDistance> findNearbyStopsViaStreets (Vertex originVertex) {
routingRequest.clampInitialWait = (0L);
routingRequest.setRoutingContext(graph, originVertex, null);
routingRequest.rctx.pathParsers = parsers;
ShortestPathTree spt = earliestArrivalSPTService.getShortestPathTree(routingRequest);
ShortestPathTree spt = earliestArrivalSearch.getShortestPathTree(routingRequest);

List<StopAtDistance> stopsFound = Lists.newArrayList();
if (spt != null) {
Expand Down
Expand Up @@ -21,7 +21,6 @@ the License, or (at your option) any later version.
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.graph.Edge;
import org.opentripplanner.routing.graph.Vertex;
import org.opentripplanner.routing.services.SPTService;
import org.opentripplanner.routing.spt.EarliestArrivalShortestPathTree;
import org.opentripplanner.routing.spt.ShortestPathTree;
import org.slf4j.Logger;
Expand All @@ -32,19 +31,19 @@ the License, or (at your option) any later version.
* Always builds a full shortest path tree ("batch mode").
*
* Note that walk limiting must be turned off -- resource limiting is not algorithmically correct.
*
* TODO this implements the deprecated SPTService interface. It should become a different SPT and dominance function implementation, rather than a "service"
*/
public class EarliestArrivalSPTService implements SPTService {
public class EarliestArrivalSearch {

private static final Logger LOG = LoggerFactory.getLogger(EarliestArrivalSPTService.class);
private static final Logger LOG = LoggerFactory.getLogger(EarliestArrivalSearch.class);

public int maxDuration = 60 * 60 * 2;

@Override
public ShortestPathTree getShortestPathTree(RoutingRequest req) {
return getShortestPathTree(req, -1, null); // negative timeout means no timeout
}

@Override
public ShortestPathTree getShortestPathTree(RoutingRequest req, double timeoutSeconds) {
return this.getShortestPathTree(req, timeoutSeconds, null);
}
Expand Down
Expand Up @@ -25,7 +25,6 @@ the License, or (at your option) any later version.
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.graph.Edge;
import org.opentripplanner.routing.graph.Vertex;
import org.opentripplanner.routing.services.SPTService;
import org.opentripplanner.routing.spt.*;
import org.opentripplanner.util.DateUtils;
import org.opentripplanner.util.monitoring.MonitoringStore;
Expand All @@ -37,8 +36,11 @@ the License, or (at your option) any later version.

/**
* Find the shortest path between graph vertices using A*.
*
* NOTE this is now per-request scoped, which has caused some threading problems in the past.
* Always make one new instance of this class per request, it contains a lot of state fields.
*/
public class GenericAStar implements SPTService { // maybe this should be wrapped in a component SPT service
public class GenericAStar {

private static final Logger LOG = LoggerFactory.getLogger(GenericAStar.class);
// FIXME this is not really a factory, it's a way to fake a global variable. This should be stored at the OTPServer level.
Expand Down Expand Up @@ -81,15 +83,13 @@ public RunState(RoutingRequest options, SearchTerminationStrategy terminationStr
/**
* Compute SPT using default timeout and termination strategy.
*/
@Override
public ShortestPathTree getShortestPathTree(RoutingRequest req) {
return getShortestPathTree(req, -1, null); // negative timeout means no timeout
}

/**
* Compute SPT using default termination strategy.
*/
@Override
public ShortestPathTree getShortestPathTree(RoutingRequest req, double relTimeoutSeconds) {
return this.getShortestPathTree(req, relTimeoutSeconds, null);
}
Expand Down
Expand Up @@ -28,6 +28,8 @@ the License, or (at your option) any later version.

/**
* Find the shortest path between graph vertices using Dijkstra's algorithm.
*
* TODO do we need this since we have GenericAStar and trivial remaining weight heuristic?
*/
public class GenericDijkstra {

Expand Down
Expand Up @@ -40,7 +40,6 @@ the License, or (at your option) any later version.
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.graph.Vertex;
import org.opentripplanner.routing.pathparser.PathParser;
import org.opentripplanner.routing.services.SPTService;
import org.opentripplanner.routing.spt.GraphPath;
import org.opentripplanner.routing.spt.ShortestPathTree;
import org.opentripplanner.routing.vertextype.TransitStop;
Expand Down Expand Up @@ -104,7 +103,7 @@ public List<GraphPath> getPaths(RoutingRequest options) {
return null;
}

SPTService sptService = new GenericAStar();
GenericAStar aStar = new GenericAStar();
if (options.rctx == null) {
options.setRoutingContext(graph);
/* Use a pathparser that constrains the search to use SimpleTransfers. */
Expand Down Expand Up @@ -144,7 +143,7 @@ public List<GraphPath> getPaths(RoutingRequest options) {
while (paths.size() < options.numItineraries && paths.size() < timeouts.length) {
double timeout = searchBeginTime + (timeouts[paths.size()] * 1000) - System.currentTimeMillis();
// if (timeout <= 0) break; ADD THIS LINE TO MAKE TIMEOUTS ACTUALLY WORK WHEN NEGATIVE
ShortestPathTree spt = sptService.getShortestPathTree(options, timeout);
ShortestPathTree spt = aStar.getShortestPathTree(options, timeout);
if (spt == null) { // timeout or other fail
LOG.warn("SPT was null.");
return null;
Expand Down

This file was deleted.

0 comments on commit 6d40355

Please sign in to comment.