use of org.opentripplanner.analyst.TimeSurface in project OpenTripPlanner by opentripplanner.
the class PropagatedTimesStore method makeSurfaces.
public TimeSurface.RangeSet makeSurfaces(RepeatedRaptorProfileRouter repeatedRaptorProfileRouter) {
TimeSurface.RangeSet rangeSet = new TimeSurface.RangeSet();
rangeSet.min = new TimeSurface(repeatedRaptorProfileRouter);
rangeSet.avg = new TimeSurface(repeatedRaptorProfileRouter);
rangeSet.max = new TimeSurface(repeatedRaptorProfileRouter);
for (Vertex vertex : graph.index.vertexForId.values()) {
int min = mins[vertex.getIndex()];
int max = maxs[vertex.getIndex()];
int avg = avgs[vertex.getIndex()];
if (avg == Integer.MAX_VALUE)
continue;
// Count is positive, extrema and sum must also be present
rangeSet.min.times.put(vertex, min);
rangeSet.max.times.put(vertex, max);
rangeSet.avg.times.put(vertex, avg);
}
return rangeSet;
}
use of org.opentripplanner.analyst.TimeSurface in project OpenTripPlanner by opentripplanner.
the class RoundBasedProfileRouter method makeSurfaces.
/**
* analyst mode: propagate to street network
*/
private void makeSurfaces() {
LOG.info("Propagating from transit stops to the street network...");
List<State> lower = Lists.newArrayList();
List<State> upper = Lists.newArrayList();
List<State> avg = Lists.newArrayList();
RoutingRequest rr = new RoutingRequest(TraverseMode.WALK);
rr.batch = (true);
rr.from = new GenericLocation(request.fromLat, request.fromLon);
rr.setRoutingContext(graph);
rr.longDistance = true;
rr.dominanceFunction = new DominanceFunction.EarliestArrival();
rr.setNumItineraries(1);
rr.worstTime = rr.dateTime + CUTOFF_SECONDS;
long startTime = rr.dateTime;
State origin = new State(rr);
// Multi-origin Dijkstra search; preinitialize the queue with states at each transit stop
for (Collection<ProfileState> pss : retainedStates.asMap().values()) {
TransitStop tstop = null;
int lowerBound = Integer.MAX_VALUE;
int upperBound = Integer.MAX_VALUE;
for (ProfileState ps : pss) {
if (tstop == null)
tstop = ps.stop;
if (ps.lowerBound < lowerBound)
lowerBound = ps.lowerBound;
if (ps.upperBound < upperBound)
upperBound = ps.upperBound;
}
if (lowerBound == Integer.MAX_VALUE || upperBound == Integer.MAX_VALUE)
throw new IllegalStateException("Invalid bound!");
lower.add(new State(tstop, null, lowerBound + startTime, startTime, rr));
upper.add(new State(tstop, null, upperBound + startTime, startTime, rr));
// TODO extremely incorrect hack!
avg.add(new State(tstop, null, (upperBound + lowerBound) / 2 + startTime, startTime, rr));
}
// get direct trips as well
lower.add(origin);
upper.add(origin);
avg.add(origin);
// create timesurfaces
timeSurfaceRangeSet = new TimeSurface.RangeSet();
AStar astar = new AStar();
timeSurfaceRangeSet.min = new TimeSurface(astar.getShortestPathTree(rr, 20, null, lower), false);
astar = new AStar();
timeSurfaceRangeSet.max = new TimeSurface(astar.getShortestPathTree(rr, 20, null, upper), false);
astar = new AStar();
timeSurfaceRangeSet.avg = new TimeSurface(astar.getShortestPathTree(rr, 20, null, avg), false);
rr.cleanup();
LOG.info("Done with propagation.");
/* Store the results in a field in the router object. */
}
use of org.opentripplanner.analyst.TimeSurface in project OpenTripPlanner by opentripplanner.
the class SurfaceResource method differenceTileGet.
/**
* Renders a raster tile for showing the difference between two TimeSurfaces.
* This service is included as a way to provide difference tiles using existing mechanisms in OTP.
* TODO However, there is some room for debate around how differences are expressed in URLs.
* We may want a more general purpose mechanism for combining time surfaces.
* For example you could make a web service request to create a time surface A-B or A+B, and the server would give
* you an ID for that surface, and then you could use that ID anywhere a surface ID is required. Perhaps internally
* there would be some sort of DifferenceTimeSurface subclass that could just drop in anywhere TimeSurface is used.
* This approach would be more stateful but more flexible.
*
* @author hannesj
*
* @param surfaceId The id of the first surface
* @param compareToSurfaceId The id of of the surface, which is compared to the first surface
*/
@Path("/{surfaceId}/differencetiles/{compareToSurfaceId}/{z}/{x}/{y}.png")
@GET
@Produces("image/png")
public Response differenceTileGet(@PathParam("surfaceId") Integer surfaceId, @PathParam("compareToSurfaceId") Integer compareToSurfaceId, @PathParam("x") int x, @PathParam("y") int y, @PathParam("z") int z) throws Exception {
Envelope2D env = SlippyTile.tile2Envelope(x, y, z);
TimeSurface surfA = otpServer.surfaceCache.get(surfaceId);
if (surfA == null)
return badRequest("Unrecognized surface ID.");
TimeSurface surfB = otpServer.surfaceCache.get(compareToSurfaceId);
if (surfB == null)
return badRequest("Unrecognized surface ID.");
if (!surfA.routerId.equals(surfB.routerId)) {
return badRequest("Both surfaces must be from the same router to perform subtraction.");
}
TileRequest tileRequest = new TileRequest(env, 256, 256);
MIMEImageFormat imageFormat = new MIMEImageFormat("image/png");
RenderRequest renderRequest = new RenderRequest(imageFormat, Layer.DIFFERENCE, Style.DIFFERENCE, true, false);
// TODO why can't the renderer be static?
Router router = otpServer.getRouter(surfA.routerId);
return router.renderer.getResponse(tileRequest, surfA, surfB, renderRequest);
}
use of org.opentripplanner.analyst.TimeSurface in project OpenTripPlanner by opentripplanner.
the class SurfaceResource method getRaster.
/**
* Produce a single grayscale raster of travel time, like travel time tiles but not broken into tiles.
*/
@Path("/{surfaceId}/raster")
@GET
@Produces("image/*")
public Response getRaster(@PathParam("surfaceId") Integer surfaceId, @QueryParam("width") @DefaultValue("1024") Integer width, @QueryParam("height") @DefaultValue("768") Integer height, @QueryParam("resolution") Double resolution, @QueryParam("time") IsoTimeParameter time, @QueryParam("format") @DefaultValue("image/geotiff") MIMEImageFormat format, @QueryParam("crs") @DefaultValue("EPSG:4326") CRSParameter crs) throws Exception {
TimeSurface surface = otpServer.surfaceCache.get(surfaceId);
Router router = otpServer.getRouter(surface.routerId);
// BoundingBox is a subclass of Envelope, an Envelope2D constructor parameter
Envelope2D bbox = new Envelope2D(router.graph.getGeomIndex().getBoundingBox(crs.crs));
if (resolution != null) {
width = (int) Math.ceil(bbox.width / resolution);
height = (int) Math.ceil(bbox.height / resolution);
}
TileRequest tileRequest = new TileRequest(bbox, width, height);
RenderRequest renderRequest = new RenderRequest(format, Layer.TRAVELTIME, Style.GRAY, false, false);
return router.renderer.getResponse(tileRequest, surface, null, renderRequest);
}
use of org.opentripplanner.analyst.TimeSurface in project OpenTripPlanner by opentripplanner.
the class SurfaceResource method createSurface.
@POST
public Response createSurface(@QueryParam("cutoffMinutes") @DefaultValue("90") int cutoffMinutes, @QueryParam("routerId") String routerId) {
// Build the request
try {
// batch must be true
RoutingRequest req = buildRequest();
// routerId is optional -- select default graph if not set
Router router = otpServer.getRouter(routerId);
req.setRoutingContext(router.graph);
EarliestArrivalSearch sptService = new EarliestArrivalSearch();
sptService.maxDuration = (60 * cutoffMinutes);
ShortestPathTree spt = sptService.getShortestPathTree(req);
req.cleanup();
if (spt != null) {
TimeSurface surface = new TimeSurface(spt);
surface.params = Maps.newHashMap();
for (Map.Entry<String, List<String>> e : uriInfo.getQueryParameters().entrySet()) {
// include only the first instance of each query parameter
surface.params.put(e.getKey(), e.getValue().get(0));
}
surface.cutoffMinutes = cutoffMinutes;
otpServer.surfaceCache.add(surface);
// .created(URI)
return Response.ok().entity(new TimeSurfaceShort(surface)).build();
} else {
return Response.noContent().entity("NO SPT").build();
}
} catch (ParameterException pex) {
return Response.status(Response.Status.BAD_REQUEST).entity("BAD USER").build();
}
}
Aggregations