@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); 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); res.add(altRsp); } return res; } catch (Exception ex) { throw new RuntimeException( "Problem while fetching path " + request.getPoints() + ": " + ex.getMessage(), ex); } }
@Override public double getEle(double lat, double lon) { lat = (int) (lat * precision) / precision; lon = (int) (lon * precision) / precision; int intKey = calcIntKey(lat, lon); HeightTile demProvider = cacheData.get(intKey); if (demProvider == null) { if (!cacheDir.exists()) cacheDir.mkdirs(); String fileDetails = getFileString(lat, lon); if (fileDetails == null) return 0; int minLat = down(lat); int minLon = down(lon); demProvider = new HeightTile(minLat, minLon, WIDTH, precision); cacheData.put(intKey, demProvider); try { String zippedURL = baseUrl + "/" + fileDetails + "hgt.zip"; File file = new File(cacheDir, new File(zippedURL).getName()); InputStream is; // get zip file if not already in cacheDir - unzip later and in-memory only! if (!file.exists()) { for (int i = 0; i < 2; i++) { try { downloader.downloadFile(zippedURL, file.getAbsolutePath()); break; } catch (FileNotFoundException ex) { // now try with point if mirror is used zippedURL = baseUrl + "/" + fileDetails + ".hgt.zip"; continue; } } } is = new FileInputStream(file); ZipInputStream zis = new ZipInputStream(is); zis.getNextEntry(); BufferedInputStream buff = new BufferedInputStream(zis); byte[] bytes = new byte[2 * WIDTH * WIDTH]; DataAccess heights = getDirectory().find("dem" + intKey); heights.create(bytes.length); demProvider.setHeights(heights); int len; while ((len = buff.read(bytes)) > 0) { for (int bytePos = 0; bytePos < len; bytePos += 2) { short val = BIT_UTIL.toShort(bytes, bytePos); if (val < -1000 || val > 10000) { // TODO fill unassigned gaps with neighbor values -> flood fill algorithm ! // -> calculate mean with an associated weight of how long the distance to the // neighbor is // throw new IllegalStateException("Invalid height value " // + val // + ", y:" + bytePos / WIDTH + ", x:" + (WIDTH - // bytePos % WIDTH)); val = Short.MIN_VALUE; } heights.setShort(bytePos, val); } } // demProvider.toImage(file.getName() + ".png"); } catch (Exception ex) { throw new RuntimeException(ex); } } short val = demProvider.getHeight(lat, lon); if (val == Short.MIN_VALUE) return Double.NaN; return val; }
@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); } }