public static PathWrapper createPathWrapper( JSONObject path, boolean tmpCalcPoints, boolean tmpInstructions, boolean tmpElevation) { 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 = jsonObj.getString("text"); 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"), 0, false); } 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("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); } // The translation is done from the routing service so just use the provided string // instead of creating a combination with sign and name etc 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; }
@Test public void testMonacoWithInstructions() { String osmFile = "files/monaco.osm.gz"; String graphFile = "target/graph-monaco"; String vehicle = "FOOT"; String importVehicles = "FOOT"; String weightCalcStr = "shortest"; try { // make sure we are using fresh graphhopper files with correct vehicle Helper.removeDir(new File(graphFile)); GraphHopper hopper = new GraphHopper() .setInMemory(true) .setOSMFile(osmFile) .disableCHShortcuts() .setGraphHopperLocation(graphFile) .setEncodingManager(new EncodingManager(importVehicles)) .importOrLoad(); Graph g = hopper.getGraph(); GHResponse rsp = hopper.route( new GHRequest(43.727687, 7.418737, 43.74958, 7.436566) .setAlgorithm("astar") .setVehicle(vehicle) .setWeighting(weightCalcStr)); assertEquals(3437.6, rsp.getDistance(), .1); assertEquals(87, rsp.getPoints().getSize()); InstructionList il = rsp.getInstructions(); assertEquals(13, il.size()); Translation tr = trMap.getWithFallBack(Locale.US); List<String> iList = il.createDescription(tr); // TODO roundabout fine tuning -> enter + leave roundabout (+ two rounabouts -> is it // necessary if we do not leave the street?) assertEquals("Continue onto Avenue des Guelfes", iList.get(0)); assertEquals("Turn slight left onto Avenue des Papalins", iList.get(1)); assertEquals("Turn sharp right onto Quai Jean-Charles Rey", iList.get(2)); assertEquals("Turn left onto road", iList.get(3)); assertEquals("Turn right onto Avenue Albert II", iList.get(4)); List<Double> dists = il.createDistances(); assertEquals(11, dists.get(0), 1); assertEquals(289, dists.get(1), 1); assertEquals(10, dists.get(2), 1); assertEquals(43, dists.get(3), 1); assertEquals(122, dists.get(4), 1); assertEquals(447, dists.get(5), 1); List<Long> times = il.createMillis(); assertEquals(7, times.get(0) / 1000); assertEquals(207, times.get(1) / 1000); assertEquals(7, times.get(2) / 1000); assertEquals(30, times.get(3) / 1000); assertEquals(87, times.get(4) / 1000); assertEquals(321, times.get(5) / 1000); List<GPXEntry> list = rsp.getInstructions().createGPXList(); assertEquals(123, list.size()); final long lastEntryMillis = list.get(list.size() - 1).getMillis(); final long totalResponseMillis = rsp.getMillis(); assertEquals(totalResponseMillis, lastEntryMillis); } catch (Exception ex) { throw new RuntimeException("cannot handle osm file " + osmFile, ex); } finally { Helper.removeDir(new File(graphFile)); } }
@Override public GHResponse route(GHRequest request) { StopWatch sw = new StopWatch().start(); double took = 0; try { String url = serviceUrl + "?point=" + request.getFrom().lat + "," + request.getFrom().lon + "&point=" + request.getTo().lat + "," + request.getTo().lon + "&type=json" + "&points_encoded=" + pointsEncoded + "&min_path_precision=" + request.getHint("douglas.minprecision", 1) + "&algo=" + request.getAlgorithm(); String str = downloader.downloadAsString(url); JSONObject json = new JSONObject(str); took = json.getJSONObject("info").getDouble("took"); JSONArray paths = json.getJSONArray("paths"); JSONObject firstPath = paths.getJSONObject(0); boolean is3D = false; if (firstPath.has("points_dim")) is3D = "3".equals(firstPath.getString("points_dim")); double distance = firstPath.getDouble("distance"); int time = firstPath.getInt("time"); PointList pointList; if (pointsEncoded) { pointList = WebHelper.decodePolyline(firstPath.getString("points"), 100, is3D); } else { JSONArray coords = firstPath.getJSONObject("points").getJSONArray("coordinates"); pointList = new PointList(coords.length(), is3D); for (int i = 0; i < coords.length(); i++) { JSONArray arr = coords.getJSONArray(i); double lon = arr.getDouble(0); double lat = arr.getDouble(1); if (is3D) pointList.add(lat, lon, arr.getDouble(2)); else pointList.add(lat, lon); } } GHResponse res = new GHResponse(); if (instructions) { JSONArray instrArr = firstPath.getJSONArray("instructions"); InstructionList il = new InstructionList(); for (int instrIndex = 0; instrIndex < instrArr.length(); instrIndex++) { JSONObject jsonObj = instrArr.getJSONObject(instrIndex); double instDist = jsonObj.getDouble("distance"); String text = jsonObj.getString("text"); 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, is3D); for (int j = from; j <= to; j++) { instPL.add(pointList, j); } // TODO way and payment type Instruction instr = new Instruction(sign, text, -1, -1, instPL).setDistance(instDist).setTime(instTime); il.add(instr); } res.setInstructions(il); } return res.setPoints(pointList).setDistance(distance).setMillis(time); } catch (Exception ex) { throw new RuntimeException( "Problem while fetching path " + request.getFrom() + "->" + request.getTo(), ex); } finally { logger.debug("Full request took:" + sw.stop().getSeconds() + ", API took:" + took); } }