Search in sources :

Example 91 with GHResponse

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

the class RouteResourceTest method testGraphHopperWebRealExceptions.

@ParameterizedTest(name = "POST = {0}")
@ValueSource(booleans = { false, true })
public void testGraphHopperWebRealExceptions(boolean usePost) {
    GraphHopperWeb hopper = new GraphHopperWeb(clientUrl(app, "/route")).setPostRequest(usePost);
    // this one actually works
    List<GHPoint> points = Arrays.asList(new GHPoint(42.554851, 1.536198), new GHPoint(42.510071, 1.548128));
    GHResponse rsp = hopper.route(new GHRequest(points).setProfile("my_car"));
    assertEquals(9204, rsp.getBest().getDistance(), 10);
    // unknown profile
    rsp = hopper.route(new GHRequest(points).setProfile("space_shuttle"));
    assertTrue(rsp.hasErrors(), rsp.getErrors().toString());
    assertTrue(rsp.getErrors().get(0).getMessage().contains("The requested profile 'space_shuttle' does not exist"), rsp.getErrors().toString());
    // unknown profile via web api
    Response response = clientTarget(app, "/route?profile=SPACE-SHUTTLE&point=42.554851,1.536198&point=42.510071,1.548128").request().buildGet().invoke();
    assertEquals(400, response.getStatus());
    String msg = (String) response.readEntity(Map.class).get("message");
    assertTrue(msg.contains("The requested profile 'SPACE-SHUTTLE' does not exist"), msg);
    // no points
    rsp = hopper.route(new GHRequest().setProfile("my_car"));
    assertFalse(rsp.getErrors().isEmpty(), "Errors expected but not found.");
    Throwable ex = rsp.getErrors().get(0);
    assertTrue(ex instanceof IllegalArgumentException, "Wrong exception found: " + ex.getClass().getName() + ", IllegalArgumentException expected.");
    assertTrue(ex.getMessage().contains("You have to pass at least one point"), ex.getMessage());
    // no points without CH
    rsp = hopper.route(new GHRequest().setProfile("my_car").putHint(Parameters.CH.DISABLE, true));
    assertFalse(rsp.getErrors().isEmpty(), "Errors expected but not found.");
    ex = rsp.getErrors().get(0);
    assertTrue(ex instanceof IllegalArgumentException, "Wrong exception found: " + ex.getClass().getName() + ", IllegalArgumentException expected.");
    assertTrue(ex.getMessage().contains("You have to pass at least one point"), ex.getMessage());
    // points out of bounds
    rsp = hopper.route(new GHRequest(0.0, 0.0, 0.0, 0.0).setProfile("my_car"));
    assertFalse(rsp.getErrors().isEmpty(), "Errors expected but not found.");
    List<Throwable> errs = rsp.getErrors();
    for (int i = 0; i < errs.size(); i++) {
        assertEquals(((PointOutOfBoundsException) errs.get(i)).getPointIndex(), i);
        assertTrue(errs.get(i).getMessage().contains("Point 0 is out of bounds: 0.0,0.0"), errs.get(i).getMessage());
    }
    // todo: add a check with too few headings, but client-hc does not support headings, #2009
    // too many curbsides
    rsp = hopper.route(new GHRequest(points).setCurbsides(Arrays.asList("right", "left", "right")).setProfile("my_car"));
    assertFalse(rsp.getErrors().isEmpty(), "Errors expected but not found.");
    assertTrue(rsp.getErrors().toString().contains("If you pass curbside, you need to pass exactly one curbside for every point"), rsp.getErrors().toString());
    // too few point hints
    rsp = hopper.route(new GHRequest(points).setPointHints(Collections.singletonList("foo")).setProfile("my_car"));
    assertFalse(rsp.getErrors().isEmpty(), "Errors expected but not found.");
    assertTrue(rsp.getErrors().toString().contains("If you pass point_hint, you need to pass exactly one hint for every point"), rsp.getErrors().toString());
    // unknown vehicle
    rsp = hopper.route(new GHRequest(points).putHint("vehicle", "SPACE-SHUTTLE"));
    assertFalse(rsp.getErrors().isEmpty(), "Errors expected but not found.");
    ex = rsp.getErrors().get(0);
    assertTrue(ex instanceof IllegalArgumentException, "Wrong exception found: " + ex.getClass().getName() + ", IllegalArgumentException expected.");
    assertTrue(ex.getMessage().contains("Vehicle not supported: `space-shuttle`. Supported are: `car`" + "\nYou should consider using the `profile` parameter instead of specifying a vehicle." + "\nAvailable profiles: [my_car]"), ex.getMessage());
    // an IllegalArgumentException from inside the core is written as JSON, unknown profile
    response = clientTarget(app, "/route?profile=SPACE-SHUTTLE&point=42.554851,1.536198&point=42.510071,1.548128").request().buildGet().invoke();
    assertEquals(400, response.getStatus());
    msg = (String) response.readEntity(Map.class).get("message");
    assertTrue(msg.contains("The requested profile 'SPACE-SHUTTLE' does not exist"), msg);
}
Also used : GHResponse(com.graphhopper.GHResponse) Response(javax.ws.rs.core.Response) GHRequest(com.graphhopper.GHRequest) GraphHopperWeb(com.graphhopper.api.GraphHopperWeb) GHPoint(com.graphhopper.util.shapes.GHPoint) GHResponse(com.graphhopper.GHResponse) GHPoint(com.graphhopper.util.shapes.GHPoint) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 92 with GHResponse

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

the class Examples method routing.

@Test
public void routing() {
    // Hint: create this thread safe instance only once in your application to allow the underlying library to cache the costly initial https handshake
    GraphHopperWeb gh = new GraphHopperWeb();
    // insert your key here
    gh.setKey(apiKey);
    // change timeout, default is 5 seconds
    gh.setDownloader(new OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).readTimeout(5, TimeUnit.SECONDS).build());
    // specify at least two coordinates
    GHRequest req = new GHRequest().addPoint(new GHPoint(49.6724, 11.3494)).addPoint(new GHPoint(49.6550, 11.4180));
    // Set vehicle like car, bike, foot, ...
    req.putHint("vehicle", "bike");
    // Optionally enable/disable elevation in output PointList, currently bike and foot support elevation, default is false
    req.putHint("elevation", false);
    // Optionally enable/disable turn instruction information, defaults is true
    req.putHint("instructions", true);
    // Optionally enable/disable path geometry information, default is true
    req.putHint("calc_points", true);
    // note: turn off instructions and calcPoints if you just need the distance or time
    // information to make calculation and transmission faster
    // Optionally set specific locale for instruction information, supports already over 25 languages,
    // defaults to English
    req.setLocale(Locale.GERMAN);
    // Optionally add path details
    req.setPathDetails(Arrays.asList(Parameters.Details.STREET_NAME, Parameters.Details.AVERAGE_SPEED, Parameters.Details.EDGE_ID));
    GHResponse fullRes = gh.route(req);
    if (fullRes.hasErrors())
        throw new RuntimeException(fullRes.getErrors().toString());
    // get best path (you will get more than one path here if you requested algorithm=alternative_route)
    ResponsePath res = fullRes.getBest();
    // get path geometry information (latitude, longitude and optionally elevation)
    PointList pl = res.getPoints();
    // distance of the full path, in meter
    double distance = res.getDistance();
    // time of the full path, in milliseconds
    long millis = res.getTime();
    // get information per turn instruction
    InstructionList il = res.getInstructions();
    for (Instruction i : il) {
    // System.out.println(i.getName());
    }
    // get path details
    List<PathDetail> pathDetails = res.getPathDetails().get(Parameters.Details.STREET_NAME);
    for (PathDetail detail : pathDetails) {
    // System.out.println(detail.getValue());
    }
}
Also used : PointList(com.graphhopper.util.PointList) InstructionList(com.graphhopper.util.InstructionList) Instruction(com.graphhopper.util.Instruction) GHResponse(com.graphhopper.GHResponse) ResponsePath(com.graphhopper.ResponsePath) PathDetail(com.graphhopper.util.details.PathDetail) GHRequest(com.graphhopper.GHRequest) GHPoint(com.graphhopper.util.shapes.GHPoint) Test(org.junit.jupiter.api.Test)

Example 93 with GHResponse

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

the class MapMatchingResource method match.

@POST
@Consumes({ MediaType.APPLICATION_XML, "application/gpx+xml" })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, "application/gpx+xml" })
public Response match(Gpx gpx, @Context HttpServletRequest request, @Context UriInfo uriInfo, @QueryParam(WAY_POINT_MAX_DISTANCE) @DefaultValue("1") double minPathPrecision, @QueryParam("type") @DefaultValue("json") String outType, @QueryParam(INSTRUCTIONS) @DefaultValue("true") boolean instructions, @QueryParam(CALC_POINTS) @DefaultValue("true") boolean calcPoints, @QueryParam("elevation") @DefaultValue("false") boolean enableElevation, @QueryParam("points_encoded") @DefaultValue("true") boolean pointsEncoded, @QueryParam("locale") @DefaultValue("en") String localeStr, @QueryParam("profile") String profile, @QueryParam(PATH_DETAILS) List<String> pathDetails, @QueryParam("gpx.route") @DefaultValue("true") boolean withRoute, @QueryParam("gpx.track") @DefaultValue("true") boolean withTrack, @QueryParam("traversal_keys") @DefaultValue("false") boolean enableTraversalKeys, @QueryParam("gps_accuracy") @DefaultValue("40") double gpsAccuracy, @QueryParam(MAX_VISITED_NODES) @DefaultValue("3000") int maxVisitedNodes) {
    boolean writeGPX = "gpx".equalsIgnoreCase(outType);
    if (gpx.trk.isEmpty()) {
        throw new IllegalArgumentException("No tracks found in GPX document. Are you using waypoints or routes instead?");
    }
    if (gpx.trk.size() > 1) {
        throw new IllegalArgumentException("GPX documents with multiple tracks not supported yet.");
    }
    instructions = writeGPX || instructions;
    StopWatch sw = new StopWatch().start();
    PMap hints = createHintsMap(uriInfo.getQueryParameters());
    // add values that are not in hints because they were explicitly listed in query params
    hints.putObject(MAX_VISITED_NODES, maxVisitedNodes);
    String weightingVehicleLogStr = "weighting: " + hints.getString("weighting", "") + ", vehicle: " + hints.getString("vehicle", "");
    if (Helper.isEmpty(profile)) {
        // resolve profile and remove legacy vehicle/weighting parameters
        // we need to explicitly disable CH here because map matching does not use it
        PMap pMap = new PMap(hints).putObject(Parameters.CH.DISABLE, true);
        profile = profileResolver.resolveProfile(pMap).getName();
        removeLegacyParameters(hints);
    }
    hints.putObject("profile", profile);
    errorIfLegacyParameters(hints);
    MapMatching matching = new MapMatching(graphHopper, hints);
    matching.setMeasurementErrorSigma(gpsAccuracy);
    List<Observation> measurements = GpxConversions.getEntries(gpx.trk.get(0));
    MatchResult matchResult = matching.match(measurements);
    // TODO: Request logging and timing should perhaps be done somewhere outside
    float took = sw.stop().getSeconds();
    String infoStr = request.getRemoteAddr() + " " + request.getLocale() + " " + request.getHeader("User-Agent");
    String logStr = request.getQueryString() + ", " + infoStr + ", took:" + took + "s, entries:" + measurements.size() + ", profile: " + profile + ", " + weightingVehicleLogStr;
    logger.info(logStr);
    if ("extended_json".equals(outType)) {
        return Response.ok(convertToTree(matchResult, enableElevation, pointsEncoded)).header("X-GH-Took", "" + Math.round(took * 1000)).build();
    } else {
        Translation tr = trMap.getWithFallBack(Helper.getLocale(localeStr));
        DouglasPeucker peucker = new DouglasPeucker().setMaxDistance(minPathPrecision);
        PathMerger pathMerger = new PathMerger(matchResult.getGraph(), matchResult.getWeighting()).setEnableInstructions(instructions).setPathDetailsBuilders(graphHopper.getPathDetailsBuilderFactory(), pathDetails).setDouglasPeucker(peucker).setSimplifyResponse(minPathPrecision > 0);
        ResponsePath responsePath = pathMerger.doWork(PointList.EMPTY, Collections.singletonList(matchResult.getMergedPath()), graphHopper.getEncodingManager(), tr);
        // GraphHopper thinks an empty path is an invalid path, and further that an invalid path is still a path but
        // marked with a non-empty list of Exception objects. I disagree, so I clear it.
        responsePath.getErrors().clear();
        GHResponse rsp = new GHResponse();
        rsp.add(responsePath);
        if (writeGPX) {
            long time = gpx.trk.get(0).getStartTime().map(Date::getTime).orElse(System.currentTimeMillis());
            return Response.ok(GpxConversions.createGPX(rsp.getBest().getInstructions(), gpx.trk.get(0).name != null ? gpx.trk.get(0).name : "", time, enableElevation, withRoute, withTrack, false, Constants.VERSION, tr), "application/gpx+xml").header("X-GH-Took", "" + Math.round(took * 1000)).build();
        } else {
            ObjectNode map = ResponsePathSerializer.jsonObject(rsp, instructions, calcPoints, enableElevation, pointsEncoded, took);
            Map<String, Object> matchStatistics = new HashMap<>();
            matchStatistics.put("distance", matchResult.getMatchLength());
            matchStatistics.put("time", matchResult.getMatchMillis());
            matchStatistics.put("original_distance", matchResult.getGpxEntriesLength());
            map.putPOJO("map_matching", matchStatistics);
            if (enableTraversalKeys) {
                List<Integer> traversalKeylist = new ArrayList<>();
                for (EdgeMatch em : matchResult.getEdgeMatches()) {
                    EdgeIteratorState edge = em.getEdgeState();
                    // encode edges as traversal keys which includes orientation, decode simply by multiplying with 0.5
                    traversalKeylist.add(GHUtility.createEdgeKey(edge.getBaseNode(), edge.getAdjNode(), edge.getEdge(), false));
                }
                map.putPOJO("traversal_keys", traversalKeylist);
            }
            return Response.ok(map).header("X-GH-Took", "" + Math.round(took * 1000)).build();
        }
    }
}
Also used : ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) GHResponse(com.graphhopper.GHResponse) ResponsePath(com.graphhopper.ResponsePath)

Example 94 with GHResponse

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

the class RouteResource method doPost.

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response doPost(@NotNull GHRequest request, @Context HttpServletRequest httpReq) {
    StopWatch sw = new StopWatch().start();
    if (request.getCustomModel() == null) {
        if (Helper.isEmpty(request.getProfile())) {
            // legacy parameter resolution (only used when there is no custom model)
            enableEdgeBasedIfThereAreCurbsides(request.getCurbsides(), request);
            request.setProfile(profileResolver.resolveProfile(request.getHints()).getName());
            removeLegacyParameters(request.getHints());
        }
    } else {
        if (Helper.isEmpty(request.getProfile()))
            // throw a dedicated exception here, otherwise a missing profile is still caught in Router
            throw new IllegalArgumentException("The 'profile' parameter is required when you use the `custom_model` parameter");
    }
    errorIfLegacyParameters(request.getHints());
    GHResponse ghResponse = graphHopper.route(request);
    boolean instructions = request.getHints().getBool(INSTRUCTIONS, true);
    boolean enableElevation = request.getHints().getBool("elevation", false);
    boolean calcPoints = request.getHints().getBool(CALC_POINTS, true);
    boolean pointsEncoded = request.getHints().getBool("points_encoded", true);
    long took = sw.stop().getNanos() / 1_000_000;
    String infoStr = httpReq.getRemoteAddr() + " " + httpReq.getLocale() + " " + httpReq.getHeader("User-Agent");
    String queryString = httpReq.getQueryString() == null ? "" : (httpReq.getQueryString() + " ");
    // todo: vehicle/weighting will always be empty at this point...
    String weightingVehicleLogStr = "weighting: " + request.getHints().getString("weighting", "") + ", vehicle: " + request.getHints().getString("vehicle", "");
    String logStr = queryString + infoStr + " " + request.getPoints().size() + ", took: " + String.format("%.1f", (double) took) + " ms, algo: " + request.getAlgorithm() + ", profile: " + request.getProfile() + ", " + weightingVehicleLogStr + ", custom_model: " + request.getCustomModel();
    if (ghResponse.hasErrors()) {
        logger.error(logStr + ", errors:" + ghResponse.getErrors());
        throw new MultiException(ghResponse.getErrors());
    } else {
        logger.info(logStr + ", alternatives: " + ghResponse.getAll().size() + ", distance0: " + ghResponse.getBest().getDistance() + ", weight0: " + ghResponse.getBest().getRouteWeight() + ", time0: " + Math.round(ghResponse.getBest().getTime() / 60000f) + "min" + ", points0: " + ghResponse.getBest().getPoints().size() + ", debugInfo: " + ghResponse.getDebugInfo());
        return Response.ok(ResponsePathSerializer.jsonObject(ghResponse, instructions, calcPoints, enableElevation, pointsEncoded, took)).header("X-GH-Took", "" + Math.round(took)).type(MediaType.APPLICATION_JSON).build();
    }
}
Also used : GHResponse(com.graphhopper.GHResponse) MultiException(com.graphhopper.jackson.MultiException)

Example 95 with GHResponse

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

the class PtRouteResourceTest method testWalkQuery.

@Test
public void testWalkQuery() {
    final Response response = clientTarget(app, "/route").queryParam("point", "36.914893,-116.76821").queryParam("point", "36.914944,-116.761472").queryParam("profile", "foot").request().buildGet().invoke();
    assertEquals(200, response.getStatus());
    GHResponse ghResponse = response.readEntity(GHResponse.class);
    assertFalse(ghResponse.hasErrors());
}
Also used : GHResponse(com.graphhopper.GHResponse) Response(javax.ws.rs.core.Response) GHResponse(com.graphhopper.GHResponse) Test(org.junit.jupiter.api.Test)

Aggregations

GHResponse (com.graphhopper.GHResponse)100 GHRequest (com.graphhopper.GHRequest)86 GHPoint (com.graphhopper.util.shapes.GHPoint)52 Test (org.junit.Test)31 Test (org.junit.jupiter.api.Test)31 GraphHopperWeb (com.graphhopper.api.GraphHopperWeb)20 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)20 ResponsePath (com.graphhopper.ResponsePath)15 EnumSource (org.junit.jupiter.params.provider.EnumSource)11 JsonNode (com.fasterxml.jackson.databind.JsonNode)9 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)9 PathWrapper (com.graphhopper.PathWrapper)9 GraphHopper (com.graphhopper.GraphHopper)7 InstructionList (com.graphhopper.util.InstructionList)7 PathDetail (com.graphhopper.util.details.PathDetail)7 GraphHopperAPI (com.graphhopper.GraphHopperAPI)6 Profile (com.graphhopper.config.Profile)5 Graph (com.graphhopper.storage.Graph)5 NodeAccess (com.graphhopper.storage.NodeAccess)5 PointNotFoundException (com.graphhopper.util.exceptions.PointNotFoundException)5