Search in sources :

Example 21 with PathWrapper

use of com.graphhopper.PathWrapper 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 {
            if (requestPoints.isEmpty()) {
                throw new IllegalArgumentException("You have to pass at least one point");
            }
            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 (!encodingManager.supports(vehicleStr)) {
                throw new IllegalArgumentException("Vehicle not supported: " + vehicleStr);
            } else if (enableElevation && !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 = 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");
            }
            List<String> pathDetails = Arrays.asList(getParams(httpReq, PATH_DETAILS));
            FlagEncoder algoVehicle = encodingManager.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).setPathDetails(pathDetails).getHints().put(CALC_POINTS, calcPoints).put(INSTRUCTIONS, enableInstructions).put(WAY_POINT_MAX_DISTANCE, minPathPrecision);
            ghRsp = graphHopper.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, objectMapper.getNodeFactory().pojoNode(map));
        else {
            writeJson(httpReq, httpRes, objectMapper.getNodeFactory().pojoNode(map));
        }
    }
}
Also used : FlagEncoder(com.graphhopper.routing.util.FlagEncoder) GHResponse(com.graphhopper.GHResponse) GHPoint(com.graphhopper.util.shapes.GHPoint) StopWatch(com.graphhopper.util.StopWatch) PathWrapper(com.graphhopper.PathWrapper) GHRequest(com.graphhopper.GHRequest) GHPoint(com.graphhopper.util.shapes.GHPoint)

Example 22 with PathWrapper

use of com.graphhopper.PathWrapper in project graphhopper by graphhopper.

the class AlternativeRoutingTemplate method isReady.

@Override
public boolean isReady(PathMerger pathMerger, Translation tr) {
    if (pathList.isEmpty())
        throw new RuntimeException("Empty paths for alternative route calculation not expected");
    // if alternative route calculation was done then create the responses from single paths
    PointList wpList = getWaypoints();
    altResponse.setWaypoints(wpList);
    ghResponse.add(altResponse);
    pathMerger.doWork(altResponse, Collections.singletonList(pathList.get(0)), tr);
    for (int index = 1; index < pathList.size(); index++) {
        PathWrapper tmpAltRsp = new PathWrapper();
        tmpAltRsp.setWaypoints(wpList);
        ghResponse.add(tmpAltRsp);
        pathMerger.doWork(tmpAltRsp, Collections.singletonList(pathList.get(index)), tr);
    }
    return true;
}
Also used : PointList(com.graphhopper.util.PointList) PathWrapper(com.graphhopper.PathWrapper) GHPoint(com.graphhopper.util.shapes.GHPoint)

Example 23 with PathWrapper

use of com.graphhopper.PathWrapper in project graphhopper by graphhopper.

the class TestAlgoCollector method assertDistance.

public TestAlgoCollector assertDistance(AlgoHelperEntry algoEntry, List<QueryResult> queryList, OneRun oneRun) {
    List<Path> altPaths = new ArrayList<>();
    QueryGraph queryGraph = new QueryGraph(algoEntry.getForQueryGraph());
    queryGraph.lookup(queryList);
    AlgorithmOptions opts = algoEntry.getAlgorithmOptions();
    FlagEncoder encoder = opts.getWeighting().getFlagEncoder();
    if (encoder.supports(TurnWeighting.class)) {
        if (!opts.getTraversalMode().isEdgeBased()) {
            errors.add("Cannot use TurnWeighting with a node based traversal");
            return this;
        }
        algoEntry.setAlgorithmOptions(AlgorithmOptions.start(opts).weighting(new TurnWeighting(opts.getWeighting(), (TurnCostExtension) queryGraph.getExtension())).build());
    }
    RoutingAlgorithmFactory factory = algoEntry.createRoutingFactory();
    for (int i = 0; i < queryList.size() - 1; i++) {
        RoutingAlgorithm algo = factory.createAlgo(queryGraph, algoEntry.getAlgorithmOptions());
        // if (!algoEntry.getExpectedAlgo().equals(algo.toString())) {
        // errors.add("Algorithm expected " + algoEntry.getExpectedAlgo() + " but was " + algo.toString());
        // return this;
        // }
        Path path = algo.calcPath(queryList.get(i).getClosestNode(), queryList.get(i + 1).getClosestNode());
        altPaths.add(path);
    }
    PathMerger pathMerger = new PathMerger().setCalcPoints(true).setSimplifyResponse(false).setEnableInstructions(true);
    PathWrapper rsp = new PathWrapper();
    pathMerger.doWork(rsp, altPaths, trMap.getWithFallBack(Locale.US));
    if (rsp.hasErrors()) {
        errors.add("response for " + algoEntry + " contains errors. Expected distance: " + oneRun.getDistance() + ", expected points: " + oneRun + ". " + queryList + ", errors:" + rsp.getErrors());
        return this;
    }
    PointList pointList = rsp.getPoints();
    double tmpDist = pointList.calcDistance(distCalc);
    if (Math.abs(rsp.getDistance() - tmpDist) > 2) {
        errors.add(algoEntry + " path.getDistance was  " + rsp.getDistance() + "\t pointList.calcDistance was " + tmpDist + "\t (expected points " + oneRun.getLocs() + ", expected distance " + oneRun.getDistance() + ") " + queryList);
    }
    if (Math.abs(rsp.getDistance() - oneRun.getDistance()) > 2) {
        errors.add(algoEntry + " returns path not matching the expected distance of " + oneRun.getDistance() + "\t Returned was " + rsp.getDistance() + "\t (expected points " + oneRun.getLocs() + ", was " + pointList.getSize() + ") " + queryList);
    }
    // There are real world instances where A-B-C is identical to A-C (in meter precision).
    if (Math.abs(pointList.getSize() - oneRun.getLocs()) > 1) {
        errors.add(algoEntry + " returns path not matching the expected points of " + oneRun.getLocs() + "\t Returned was " + pointList.getSize() + "\t (expected distance " + oneRun.getDistance() + ", was " + rsp.getDistance() + ") " + queryList);
    }
    return this;
}
Also used : TurnWeighting(com.graphhopper.routing.weighting.TurnWeighting) ArrayList(java.util.ArrayList) GHPoint(com.graphhopper.util.shapes.GHPoint) PathWrapper(com.graphhopper.PathWrapper) TurnCostExtension(com.graphhopper.storage.TurnCostExtension)

Example 24 with PathWrapper

use of com.graphhopper.PathWrapper in project graphhopper by graphhopper.

the class GraphHopperWeb method createPathWrapper.

public static PathWrapper createPathWrapper(JSONObject path, boolean tmpCalcPoints, boolean tmpInstructions, boolean tmpElevation, boolean turnDescription) {
    PathWrapper pathWrapper = new PathWrapper();
    pathWrapper.addErrors(readErrors(path));
    if (pathWrapper.hasErrors())
        return pathWrapper;
    if (path.has("snapped_waypoints")) {
        String snappedPointStr = path.getString("snapped_waypoints");
        PointList snappedPoints = WebHelper.decodePolyline(snappedPointStr, 5, tmpElevation);
        pathWrapper.setWaypoints(snappedPoints);
    }
    if (tmpCalcPoints) {
        String pointStr = path.getString("points");
        PointList pointList = WebHelper.decodePolyline(pointStr, 100, tmpElevation);
        pathWrapper.setPoints(pointList);
        if (tmpInstructions) {
            JSONArray instrArr = path.getJSONArray("instructions");
            InstructionList il = new InstructionList(null);
            int viaCount = 1;
            for (int instrIndex = 0; instrIndex < instrArr.length(); instrIndex++) {
                JSONObject jsonObj = instrArr.getJSONObject(instrIndex);
                double instDist = jsonObj.getDouble("distance");
                String text = turnDescription ? jsonObj.getString("text") : jsonObj.getString("street_name");
                long instTime = jsonObj.getLong("time");
                int sign = jsonObj.getInt("sign");
                JSONArray iv = jsonObj.getJSONArray("interval");
                int from = iv.getInt(0);
                int to = iv.getInt(1);
                PointList instPL = new PointList(to - from, tmpElevation);
                for (int j = from; j <= to; j++) {
                    instPL.add(pointList, j);
                }
                InstructionAnnotation ia = InstructionAnnotation.EMPTY;
                if (jsonObj.has("annotation_importance") && jsonObj.has("annotation_text")) {
                    ia = new InstructionAnnotation(jsonObj.getInt("annotation_importance"), jsonObj.getString("annotation_text"));
                }
                Instruction instr;
                if (sign == Instruction.USE_ROUNDABOUT || sign == Instruction.LEAVE_ROUNDABOUT) {
                    RoundaboutInstruction ri = new RoundaboutInstruction(sign, text, ia, instPL);
                    if (jsonObj.has("exit_number")) {
                        ri.setExitNumber(jsonObj.getInt("exit_number"));
                    }
                    if (jsonObj.has("exited")) {
                        if (jsonObj.getBoolean("exited"))
                            ri.setExited();
                    }
                    if (jsonObj.has("turn_angle")) {
                        // TODO provide setTurnAngle setter
                        double angle = jsonObj.getDouble("turn_angle");
                        ri.setDirOfRotation(angle);
                        ri.setRadian((angle < 0 ? -Math.PI : Math.PI) - angle);
                    }
                    instr = ri;
                } else if (sign == Instruction.REACHED_VIA) {
                    ViaInstruction tmpInstr = new ViaInstruction(text, ia, instPL);
                    tmpInstr.setViaCount(viaCount);
                    viaCount++;
                    instr = tmpInstr;
                } else if (sign == Instruction.FINISH) {
                    instr = new FinishInstruction(instPL, 0);
                } else {
                    instr = new Instruction(sign, text, ia, instPL);
                }
                // This can be changed by passing <code>turn_description=false</code>.
                if (turnDescription)
                    instr.setUseRawName();
                instr.setDistance(instDist).setTime(instTime);
                il.add(instr);
            }
            pathWrapper.setInstructions(il);
        }
    }
    double distance = path.getDouble("distance");
    long time = path.getLong("time");
    pathWrapper.setDistance(distance).setTime(time);
    return pathWrapper;
}
Also used : JSONArray(org.json.JSONArray) GHPoint(com.graphhopper.util.shapes.GHPoint) PathWrapper(com.graphhopper.PathWrapper) JSONObject(org.json.JSONObject)

Example 25 with PathWrapper

use of com.graphhopper.PathWrapper in project graphhopper by graphhopper.

the class GraphHopperWeb method route.

@Override
public GHResponse route(GHRequest request) {
    try {
        String places = "";
        for (GHPoint p : request.getPoints()) {
            places += "point=" + p.lat + "," + p.lon + "&";
        }
        boolean tmpInstructions = request.getHints().getBool("instructions", instructions);
        boolean tmpCalcPoints = request.getHints().getBool("calc_points", calcPoints);
        boolean tmpTurnDescription = request.getHints().getBool("turn_description", turnDescription);
        if (tmpInstructions && !tmpCalcPoints)
            throw new IllegalStateException("Cannot calculate instructions without points (only points without instructions). " + "Use calc_points=false and instructions=false to disable point and instruction calculation");
        boolean tmpElevation = request.getHints().getBool("elevation", elevation);
        String url = routeServiceUrl + "?" + places + "&type=json" + "&instructions=" + tmpInstructions + "&points_encoded=true" + "&calc_points=" + tmpCalcPoints + "&algorithm=" + request.getAlgorithm() + "&locale=" + request.getLocale().toString() + "&elevation=" + tmpElevation;
        if (!request.getVehicle().isEmpty())
            url += "&vehicle=" + request.getVehicle();
        if (!key.isEmpty())
            url += "&key=" + key;
        for (Entry<String, String> entry : request.getHints().toMap().entrySet()) {
            String urlKey = entry.getKey();
            String urlValue = entry.getValue();
            // use lower case conversion for check only!
            if (ignoreSet.contains(urlKey.toLowerCase()))
                continue;
            if (urlValue != null && !urlValue.isEmpty())
                url += "&" + WebHelper.encodeURL(urlKey) + "=" + WebHelper.encodeURL(urlValue);
        }
        String str = downloader.downloadAsString(url, true);
        JSONObject json = new JSONObject(str);
        GHResponse res = new GHResponse();
        res.addErrors(readErrors(json));
        if (res.hasErrors())
            return res;
        JSONArray paths = json.getJSONArray("paths");
        for (int index = 0; index < paths.length(); index++) {
            JSONObject path = paths.getJSONObject(index);
            PathWrapper altRsp = createPathWrapper(path, tmpCalcPoints, tmpInstructions, tmpElevation, tmpTurnDescription);
            res.add(altRsp);
        }
        return res;
    } catch (Exception ex) {
        throw new RuntimeException("Problem while fetching path " + request.getPoints() + ": " + ex.getMessage(), ex);
    }
}
Also used : DetailedRuntimeException(com.graphhopper.util.exceptions.DetailedRuntimeException) JSONObject(org.json.JSONObject) PathWrapper(com.graphhopper.PathWrapper) JSONArray(org.json.JSONArray) GHPoint(com.graphhopper.util.shapes.GHPoint) GHResponse(com.graphhopper.GHResponse) GHPoint(com.graphhopper.util.shapes.GHPoint) DetailedRuntimeException(com.graphhopper.util.exceptions.DetailedRuntimeException) PointOutOfBoundsException(com.graphhopper.util.exceptions.PointOutOfBoundsException) PointNotFoundException(com.graphhopper.util.exceptions.PointNotFoundException) DetailedIllegalArgumentException(com.graphhopper.util.exceptions.DetailedIllegalArgumentException) JSONException(org.json.JSONException) ConnectionNotFoundException(com.graphhopper.util.exceptions.ConnectionNotFoundException)

Aggregations

PathWrapper (com.graphhopper.PathWrapper)25 GHPoint (com.graphhopper.util.shapes.GHPoint)14 Test (org.junit.Test)14 GHRequest (com.graphhopper.GHRequest)13 GHResponse (com.graphhopper.GHResponse)13 JsonNode (com.fasterxml.jackson.databind.JsonNode)3 Graph (com.graphhopper.storage.Graph)2 NodeAccess (com.graphhopper.storage.NodeAccess)2 PointList (com.graphhopper.util.PointList)2 PathDetail (com.graphhopper.util.details.PathDetail)2 JSONArray (org.json.JSONArray)2 JSONObject (org.json.JSONObject)2 GTFSFeed (com.conveyal.gtfs.GTFSFeed)1 Stop (com.conveyal.gtfs.model.Stop)1 StopTime (com.conveyal.gtfs.model.StopTime)1 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)1 GtfsRealtime (com.google.transit.realtime.GtfsRealtime)1 GraphHopperAPI (com.graphhopper.GraphHopperAPI)1 Trip (com.graphhopper.Trip)1