use of com.graphhopper.ResponsePath in project graphhopper by graphhopper.
the class PathSimplificationTest method testScenario.
@Test
public void testScenario() {
Graph g = new GraphBuilder(carManager).create();
// 0-1-2
// | | |
// 3-4-5 9-10
// | | | |
// 6-7-8--*
NodeAccess na = g.getNodeAccess();
na.setNode(0, 1.2, 1.0);
na.setNode(1, 1.2, 1.1);
na.setNode(2, 1.2, 1.2);
na.setNode(3, 1.1, 1.0);
na.setNode(4, 1.1, 1.1);
na.setNode(5, 1.1, 1.2);
na.setNode(9, 1.1, 1.3);
na.setNode(10, 1.1, 1.4);
na.setNode(6, 1.0, 1.0);
na.setNode(7, 1.0, 1.1);
na.setNode(8, 1.0, 1.2);
ReaderWay w = new ReaderWay(1);
w.setTag("highway", "tertiary");
w.setTag("maxspeed", "10");
IntsRef relFlags = carManager.createRelationFlags();
EdgeIteratorState tmpEdge;
tmpEdge = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 1).setDistance(10000)).setName("0-1");
assertNotEquals(EncodingManager.Access.CAN_SKIP, carEncoder.getAccess(w));
tmpEdge.setFlags(carManager.handleWayTags(w, relFlags));
tmpEdge = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(1, 2).setDistance(11000)).setName("1-2");
tmpEdge.setFlags(carManager.handleWayTags(w, relFlags));
w.setTag("maxspeed", "20");
tmpEdge = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 3).setDistance(11000));
tmpEdge.setFlags(carManager.handleWayTags(w, relFlags));
tmpEdge = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(1, 4).setDistance(10000)).setName("1-4");
tmpEdge.setFlags(carManager.handleWayTags(w, relFlags));
tmpEdge = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 5).setDistance(11000)).setName("5-2");
tmpEdge.setFlags(carManager.handleWayTags(w, relFlags));
w.setTag("maxspeed", "30");
tmpEdge = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(3, 6).setDistance(11000)).setName("3-6");
tmpEdge.setFlags(carManager.handleWayTags(w, relFlags));
tmpEdge = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(4, 7).setDistance(10000)).setName("4-7");
tmpEdge.setFlags(carManager.handleWayTags(w, relFlags));
tmpEdge = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(5, 8).setDistance(10000)).setName("5-8");
tmpEdge.setFlags(carManager.handleWayTags(w, relFlags));
w.setTag("maxspeed", "40");
tmpEdge = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(6, 7).setDistance(11000)).setName("6-7");
tmpEdge.setFlags(carManager.handleWayTags(w, relFlags));
tmpEdge = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(7, 8).setDistance(10000));
PointList list = new PointList();
list.add(1.0, 1.15);
list.add(1.0, 1.16);
tmpEdge.setWayGeometry(list);
tmpEdge.setName("7-8");
tmpEdge.setFlags(carManager.handleWayTags(w, relFlags));
w.setTag("maxspeed", "50");
// missing edge name
tmpEdge = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(9, 10).setDistance(10000));
tmpEdge.setFlags(carManager.handleWayTags(w, relFlags));
tmpEdge = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(8, 9).setDistance(20000));
list.clear();
list.add(1.0, 1.3);
list.add(1.0, 1.3001);
list.add(1.0, 1.3002);
list.add(1.0, 1.3003);
tmpEdge.setName("8-9");
tmpEdge.setWayGeometry(list);
tmpEdge.setFlags(carManager.handleWayTags(w, relFlags));
// Path is: [0 0-1, 3 1-4, 6 4-7, 9 7-8, 11 8-9, 10 9-10]
ShortestWeighting weighting = new ShortestWeighting(carEncoder);
Path p = new Dijkstra(g, weighting, tMode).calcPath(0, 10);
InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, carManager, usTR);
Map<String, List<PathDetail>> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, Arrays.asList(AVERAGE_SPEED), new PathDetailsBuilderFactory(), 0);
ResponsePath responsePath = new ResponsePath();
responsePath.setInstructions(wayList);
responsePath.addPathDetails(details);
responsePath.setPoints(p.calcPoints());
int numberOfPoints = p.calcPoints().size();
DouglasPeucker douglasPeucker = new DouglasPeucker();
// Do not simplify anything
douglasPeucker.setMaxDistance(0);
PathSimplification.simplify(responsePath, douglasPeucker, true);
assertEquals(numberOfPoints, responsePath.getPoints().size());
responsePath = new ResponsePath();
responsePath.setInstructions(wayList);
responsePath.addPathDetails(details);
responsePath.setPoints(p.calcPoints());
douglasPeucker.setMaxDistance(100000000);
PathSimplification.simplify(responsePath, douglasPeucker, true);
assertTrue(numberOfPoints > responsePath.getPoints().size());
}
use of com.graphhopper.ResponsePath in project graphhopper by graphhopper.
the class RouteResourceClientHCTest method testPathDetails.
@ParameterizedTest
@EnumSource(value = TestParam.class)
public void testPathDetails(TestParam p) {
GraphHopperWeb gh = createGH(p);
GHRequest req = new GHRequest().addPoint(new GHPoint(42.507065, 1.529846)).addPoint(new GHPoint(42.510383, 1.533392)).setProfile("my_car");
req.getPathDetails().add("average_speed");
GHResponse res = gh.route(req);
assertFalse(res.hasErrors(), "errors:" + res.getErrors().toString());
ResponsePath alt = res.getBest();
assertEquals(1, alt.getPathDetails().size());
List<PathDetail> details = alt.getPathDetails().get("average_speed");
assertFalse(details.isEmpty());
assertTrue((Double) details.get(0).getValue() > 20);
assertTrue((Double) details.get(0).getValue() < 70);
}
use of com.graphhopper.ResponsePath in project graphhopper by graphhopper.
the class RouteResourceClientHCTest method testSimpleRoute.
@ParameterizedTest
@EnumSource(value = TestParam.class)
public void testSimpleRoute(TestParam p) {
GraphHopperWeb gh = createGH(p);
GHRequest req = new GHRequest().addPoint(new GHPoint(42.5093, 1.5274)).addPoint(new GHPoint(42.5126, 1.5410)).putHint("vehicle", "car").putHint("elevation", false).putHint("instructions", true).putHint("calc_points", true);
GHResponse rsp = gh.route(req);
assertFalse(rsp.hasErrors(), "errors:" + rsp.getErrors().toString());
ResponsePath res = rsp.getBest();
isBetween(60, 70, res.getPoints().size());
isBetween(2900, 3000, res.getDistance());
isBetween(110, 120, res.getAscend());
isBetween(70, 80, res.getDescend());
isBetween(190, 200, res.getRouteWeight());
// change vehicle
rsp = gh.route(new GHRequest(42.5093, 1.5274, 42.5126, 1.5410).putHint("vehicle", "bike"));
res = rsp.getBest();
assertFalse(rsp.hasErrors(), "errors:" + rsp.getErrors().toString());
isBetween(2500, 2600, res.getDistance());
assertEquals("[0, 1]", res.getPointsOrder().toString());
}
use of com.graphhopper.ResponsePath 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());
}
}
use of com.graphhopper.ResponsePath 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();
}
}
}
Aggregations