package org.opentripplanner.api.resource;
import org.joda.time.LocalDate;
import org.onebusaway.gtfs.model.AgencyAndId;
import org.onebusaway.gtfs.model.Stop;
import org.opentripplanner.analyst.SurfaceCache;
import org.opentripplanner.analyst.TimeSurface;
import org.opentripplanner.api.param.LatLon;
import org.opentripplanner.api.parameter.QualifiedModeSet;
import org.opentripplanner.profile.ProfileRequest;
import org.opentripplanner.profile.RepeatedRaptorProfileRouter;
import org.opentripplanner.routing.core.TraverseModeSet;
import org.opentripplanner.routing.error.VertexNotFoundException;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.graph.Vertex;
import org.opentripplanner.standalone.OTPServer;
import org.opentripplanner.standalone.Router;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Collection;
/**
* For debugging
*/
@Path("routers/{routerId}/rrtr")
public class RepeatedRaptorTestResource {
private static final Logger LOG = LoggerFactory.getLogger(ProfileResource.class);
private Graph graph;
private SurfaceCache surfaceCache;
private int n_increase = 0;
private int n_decrease= 0;
private int n_total = 0;
private long sum_decrease = 0;
public RepeatedRaptorTestResource (@Context OTPServer otpServer, @PathParam("routerId") String routerId) {
Router router = otpServer.getRouter(routerId);
graph = router.graph;
surfaceCache = otpServer.surfaceCache;
}
@GET
@Produces({ MediaType.APPLICATION_JSON })
public Response profileRoute (
@QueryParam("from") LatLon from,
@QueryParam("fromStop") String fromStopString,
@QueryParam("banAgency") String banAgency,
@QueryParam("banRoute") String banRouteString) {
if (from != null) {
oneOrigin(from.lat, from.lon, banAgency);
} else {
Collection<Stop> originStops = new ArrayList<>();
if (fromStopString != null) {
String[] fields = fromStopString.split(":");
originStops.add(graph.index.stopForId.get(new AgencyAndId(fields[0], fields[1])));
} else {
originStops = graph.index.stopForId.values();
}
LOG.info("from stops {}", originStops);
for (Stop stop : originStops) {
LOG.info("{}/{}: {}", 0, originStops.size(), stop);
// Shift slightly so we don't always search right on top of a transit stop.
oneOrigin(stop.getLat() + 0.001, stop.getLon() + 0.001, banAgency);
}
}
return Response.ok().entity("OK\n").build();
}
private void oneOrigin (double lat, double lon, String banAgency) {
ProfileRequest req = new ProfileRequest();
req.fromLat = lat;
req.fromLon = lon;
req.fromTime = 60 * 60 * 8;
req.toTime = 60 * 60 * 9;
req.walkSpeed = 2;
req.bikeSpeed = 4;
req.carSpeed = 8;
req.date = new LocalDate(2015, 04, 20);
req.maxWalkTime = 20; // minutes
req.accessModes = new QualifiedModeSet("WALK");
req.egressModes = new QualifiedModeSet("WALK");
req.transitModes = new TraverseModeSet("TRANSIT");
req.analyst = true;
if (surfaceCache == null) {
LOG.error("You must run OTP with the --analyst option to enable spatial analysis features.");
}
final RepeatedRaptorProfileRouter router_a = new RepeatedRaptorProfileRouter(graph, req);
final RepeatedRaptorProfileRouter router_b = new RepeatedRaptorProfileRouter(graph, req);
router_b.banAgency = banAgency;
try {
router_a.route();
router_b.route();
} catch (VertexNotFoundException ex) {
LOG.error("vertex not found");
return;
}
System.out.printf("stop, min_a, min_b, min_diff, max_a, max_b, max_diff\n");
boolean decreased = false;
// Compare the propagated results
decreased = false;
TimeSurface.RangeSet timeSurfaces_a = router_a.timeSurfaceRangeSet;
TimeSurface.RangeSet timeSurfaces_b = router_b.timeSurfaceRangeSet;
for (Vertex destVertex : timeSurfaces_a.min.times.keySet()) {
int min_a = timeSurfaces_a.min.getTime(destVertex);
int max_a = timeSurfaces_a.max.getTime(destVertex);
int avg_a = timeSurfaces_a.avg.getTime(destVertex);
int min_b = timeSurfaces_b.min.getTime(destVertex);
int max_b = timeSurfaces_b.max.getTime(destVertex);
int avg_b = timeSurfaces_b.avg.getTime(destVertex);
long min_diff = (long) min_b - min_a;
long max_diff = (long) max_b - max_a;
long avg_diff = (long) avg_b - avg_a;
if (min_b == TimeSurface.UNREACHABLE) {
min_diff = Integer.MAX_VALUE;
max_diff = Integer.MAX_VALUE;
avg_diff = Integer.MAX_VALUE;
}
n_total += 1;
if (min_diff < 0 || max_diff < 0 || avg_diff < 0) {
n_decrease += 1;
sum_decrease += max_diff;
// Time decreased due to banning a route. This is bad, print it out.
System.out.printf("\"%s\",%d,%d,%d,%d,%d,%d\n",
destVertex.getName(), min_a, min_b, min_diff, max_a, max_b, max_diff);
decreased = true;
} else if (avg_diff > 0) {
n_increase += 1;
}
}
if (decreased) {
LOG.error("Decreases happened at propagated street vertices for this origin!");
}
LOG.info("Street Vertices: {} increased, {} decreased out of {} destinations total", n_increase, n_decrease, n_total);
}
}