use of com.graphhopper.util.StopWatch in project graphhopper by graphhopper.
the class ViaRoutingTemplate method calcPaths.
@Override
public List<Path> calcPaths(QueryGraph queryGraph, RoutingAlgorithmFactory algoFactory, AlgorithmOptions algoOpts) {
long visitedNodesSum = 0L;
boolean viaTurnPenalty = ghRequest.getHints().getBool(Routing.PASS_THROUGH, false);
int pointCounts = ghRequest.getPoints().size();
pathList = new ArrayList<>(pointCounts - 1);
QueryResult fromQResult = queryResults.get(0);
StopWatch sw;
for (int placeIndex = 1; placeIndex < pointCounts; placeIndex++) {
if (placeIndex == 1) {
// enforce start direction
queryGraph.enforceHeading(fromQResult.getClosestNode(), ghRequest.getFavoredHeading(0), false);
} else if (viaTurnPenalty) {
// enforce straight start after via stop
Path prevRoute = pathList.get(placeIndex - 2);
if (prevRoute.getEdgeCount() > 0) {
EdgeIteratorState incomingVirtualEdge = prevRoute.getFinalEdge();
queryGraph.unfavorVirtualEdgePair(fromQResult.getClosestNode(), incomingVirtualEdge.getEdge());
}
}
QueryResult toQResult = queryResults.get(placeIndex);
// enforce end direction
queryGraph.enforceHeading(toQResult.getClosestNode(), ghRequest.getFavoredHeading(placeIndex), true);
sw = new StopWatch().start();
RoutingAlgorithm algo = algoFactory.createAlgo(queryGraph, algoOpts);
String debug = ", algoInit:" + sw.stop().getSeconds() + "s";
sw = new StopWatch().start();
List<Path> tmpPathList = algo.calcPaths(fromQResult.getClosestNode(), toQResult.getClosestNode());
debug += ", " + algo.getName() + "-routing:" + sw.stop().getSeconds() + "s";
if (tmpPathList.isEmpty())
throw new IllegalStateException("At least one path has to be returned for " + fromQResult + " -> " + toQResult);
for (Path path : tmpPathList) {
if (path.getTime() < 0)
throw new RuntimeException("Time was negative. Please report as bug and include:" + ghRequest);
pathList.add(path);
debug += ", " + path.getDebugInfo();
}
altResponse.addDebugInfo(debug);
// reset all direction enforcements in queryGraph to avoid influencing next path
queryGraph.clearUnfavoredStatus();
if (algo.getVisitedNodes() >= algoOpts.getMaxVisitedNodes())
throw new IllegalArgumentException("No path found due to maximum nodes exceeded " + algoOpts.getMaxVisitedNodes());
visitedNodesSum += algo.getVisitedNodes();
fromQResult = toQResult;
}
ghResponse.getHints().put("visited_nodes.sum", visitedNodesSum);
ghResponse.getHints().put("visited_nodes.average", (float) visitedNodesSum / (pointCounts - 1));
return pathList;
}
use of com.graphhopper.util.StopWatch in project graphhopper by graphhopper.
the class PrepareLandmarks method doWork.
@Override
public void doWork() {
super.doWork();
StopWatch sw = new StopWatch().start();
LOGGER.info("Start calculating " + lms.getLandmarkCount() + " landmarks, default active lms:" + defaultActiveLandmarks + ", weighting:" + lms.getLmSelectionWeighting() + ", " + Helper.getMemInfo());
lms.createLandmarks();
lms.flush();
LOGGER.info("Calculating landmarks for " + (lms.getSubnetworksWithLandmarks() - 1) + " subnetworks took:" + sw.stop().getSeconds() + " => " + lms.getLandmarksAsGeoJSON() + ", stored weights:" + lms.getLandmarkCount() + ", nodes:" + graph.getNodes() + ", " + Helper.getMemInfo());
}
use of com.graphhopper.util.StopWatch in project graphhopper by graphhopper.
the class Location2IDQuadtree method prepareIndex.
/**
* Fill quadtree which will span a raster over the entire specified graph g. But do this in a
* pre-defined resolution which is controlled via capacity. This data structure then uses approx.
* capacity * 4 bytes. So maximum capacity is 2^30 where the quadtree would cover the world
* boundaries every 1.3km - IMO enough for EU or US networks.
*/
@Override
public LocationIndex prepareIndex() {
initBuffer();
initAlgo(latSize, lonSize);
StopWatch sw = new StopWatch().start();
GHBitSet filledIndices = fillQuadtree(latSize * lonSize);
int fillQT = filledIndices.getCardinality();
float res1 = sw.stop().getSeconds();
sw = new StopWatch().start();
int counter = fillEmptyIndices(filledIndices);
float fillEmpty = sw.stop().getSeconds();
logger.info("filled quadtree index array in " + res1 + "s. size is " + getCapacity() + " (" + fillQT + "). filled empty " + counter + " in " + fillEmpty + "s");
flush();
return this;
}
use of com.graphhopper.util.StopWatch in project graphhopper by graphhopper.
the class ChangeGraphServlet method doPost.
@Override
protected void doPost(HttpServletRequest httpReq, HttpServletResponse httpRes) throws ServletException, IOException {
String infoStr = httpReq.getRemoteAddr() + " " + httpReq.getPathInfo() + " " + httpReq.getQueryString();
float took = -1;
StopWatch sw = new StopWatch().start();
try {
JsonFeatureCollection collection = gson.fromJson(new InputStreamReader(httpReq.getInputStream(), Helper.UTF_CS), JsonFeatureCollection.class);
// TODO make asynchronous!
ChangeGraphResponse rsp = hopper.changeGraph(collection.getFeatures());
JSONObject resObject = new JSONObject();
resObject.put("updates", rsp.getUpdateCount());
// prepare the consumer to get some changes not immediately when returning after POST
resObject.put("scheduled_updates", 0);
httpRes.setHeader("X-GH-Took", "" + Math.round(took * 1000));
writeJson(httpReq, httpRes, resObject);
took = sw.stop().getSeconds();
logger.info(infoStr + " " + took);
} catch (IllegalArgumentException ex) {
took = sw.stop().getSeconds();
logger.warn(infoStr + " " + took + ", " + ex.getMessage());
writeError(httpRes, 400, "Wrong arguments for endpoint /change, " + infoStr);
} catch (Exception ex) {
took = sw.stop().getSeconds();
logger.error(infoStr + " " + took, ex);
writeError(httpRes, 500, "Error at endpoint /change, " + infoStr);
}
}
use of com.graphhopper.util.StopWatch in project graphhopper by graphhopper.
the class GraphHopperServlet method doGet.
@Override
public void doGet(HttpServletRequest httpReq, HttpServletResponse httpRes) throws ServletException, IOException {
List<GHPoint> requestPoints = getPoints(httpReq, "point");
GHResponse ghRsp = new GHResponse();
double minPathPrecision = getDoubleParam(httpReq, WAY_POINT_MAX_DISTANCE, 1d);
boolean writeGPX = "gpx".equalsIgnoreCase(getParam(httpReq, "type", "json"));
boolean enableInstructions = writeGPX || getBooleanParam(httpReq, INSTRUCTIONS, true);
boolean calcPoints = getBooleanParam(httpReq, CALC_POINTS, true);
boolean enableElevation = getBooleanParam(httpReq, "elevation", false);
boolean pointsEncoded = getBooleanParam(httpReq, "points_encoded", true);
String vehicleStr = getParam(httpReq, "vehicle", "car");
String weighting = getParam(httpReq, "weighting", "fastest");
String algoStr = getParam(httpReq, "algorithm", "");
String localeStr = getParam(httpReq, "locale", "en");
StopWatch sw = new StopWatch().start();
if (!ghRsp.hasErrors()) {
try {
List<Double> favoredHeadings = Collections.EMPTY_LIST;
try {
favoredHeadings = getDoubleParamList(httpReq, "heading");
} catch (NumberFormatException e) {
throw new IllegalArgumentException("heading list in wrong format: " + e.getMessage());
}
if (!hopper.getEncodingManager().supports(vehicleStr)) {
throw new IllegalArgumentException("Vehicle not supported: " + vehicleStr);
} else if (enableElevation && !hopper.hasElevation()) {
throw new IllegalArgumentException("Elevation not supported!");
} else if (favoredHeadings.size() > 1 && favoredHeadings.size() != requestPoints.size()) {
throw new IllegalArgumentException("The number of 'heading' parameters must be <= 1 " + "or equal to the number of points (" + requestPoints.size() + ")");
}
List<String> pointHints = new ArrayList<String>(Arrays.asList(getParams(httpReq, POINT_HINT)));
if (pointHints.size() > 0 && pointHints.size() != requestPoints.size()) {
throw new IllegalArgumentException("If you pass " + POINT_HINT + ", you need to pass a hint for every point, empty hints will be ignored");
}
FlagEncoder algoVehicle = hopper.getEncodingManager().getEncoder(vehicleStr);
GHRequest request;
if (favoredHeadings.size() > 0) {
// if only one favored heading is specified take as start heading
if (favoredHeadings.size() == 1) {
List<Double> paddedHeadings = new ArrayList<Double>(Collections.nCopies(requestPoints.size(), Double.NaN));
paddedHeadings.set(0, favoredHeadings.get(0));
request = new GHRequest(requestPoints, paddedHeadings);
} else {
request = new GHRequest(requestPoints, favoredHeadings);
}
} else {
request = new GHRequest(requestPoints);
}
initHints(request.getHints(), httpReq.getParameterMap());
request.setVehicle(algoVehicle.toString()).setWeighting(weighting).setAlgorithm(algoStr).setLocale(localeStr).setPointHints(pointHints).getHints().put(CALC_POINTS, calcPoints).put(INSTRUCTIONS, enableInstructions).put(WAY_POINT_MAX_DISTANCE, minPathPrecision);
ghRsp = hopper.route(request);
} catch (IllegalArgumentException ex) {
ghRsp.addError(ex);
}
}
float took = sw.stop().getSeconds();
String infoStr = httpReq.getRemoteAddr() + " " + httpReq.getLocale() + " " + httpReq.getHeader("User-Agent");
String logStr = httpReq.getQueryString() + " " + infoStr + " " + requestPoints + ", took:" + took + ", " + algoStr + ", " + weighting + ", " + vehicleStr;
httpRes.setHeader("X-GH-Took", "" + Math.round(took * 1000));
int alternatives = ghRsp.getAll().size();
if (writeGPX && alternatives > 1)
ghRsp.addError(new IllegalArgumentException("Alternatives are currently not yet supported for GPX"));
if (ghRsp.hasErrors()) {
logger.error(logStr + ", errors:" + ghRsp.getErrors());
} else {
PathWrapper altRsp0 = ghRsp.getBest();
logger.info(logStr + ", alternatives: " + alternatives + ", distance0: " + altRsp0.getDistance() + ", time0: " + Math.round(altRsp0.getTime() / 60000f) + "min" + ", points0: " + altRsp0.getPoints().getSize() + ", debugInfo: " + ghRsp.getDebugInfo());
}
if (writeGPX) {
if (ghRsp.hasErrors()) {
httpRes.setStatus(SC_BAD_REQUEST);
httpRes.getWriter().append(errorsToXML(ghRsp.getErrors()));
} else {
// no error => we can now safely call getFirst
String xml = createGPXString(httpReq, httpRes, ghRsp.getBest());
writeResponse(httpRes, xml);
}
} else {
Map<String, Object> map = routeSerializer.toJSON(ghRsp, calcPoints, pointsEncoded, enableElevation, enableInstructions);
Object infoMap = map.get("info");
if (infoMap != null)
((Map) infoMap).put("took", Math.round(took * 1000));
if (ghRsp.hasErrors())
writeJsonError(httpRes, SC_BAD_REQUEST, new JSONObject(map));
else {
writeJson(httpReq, httpRes, new JSONObject(map));
}
}
}
Aggregations