@Override public void doPost(HttpServletRequest httpReq, HttpServletResponse httpRes) throws ServletException, IOException { String infoStr = httpReq.getRemoteAddr() + " " + httpReq.getLocale() + " " + httpReq.getHeader("User-Agent"); String type = httpReq.getContentType(); GPXFile gpxFile; if (type.contains("application/xml")) { try { gpxFile = parseXML(httpReq); } catch (Exception ex) { logger.warn("Cannot parse XML for " + httpReq.getQueryString() + ", " + infoStr); httpRes.setStatus(SC_BAD_REQUEST); httpRes.getWriter().append(errorsToXML(Collections.<Throwable>singletonList(ex))); return; } } else { throw new IllegalArgumentException("content type not supported " + type); } final String format = getParam(httpReq, "type", "json"); boolean writeGPX = GPX_FORMAT.equals(format); boolean pointsEncoded = getBooleanParam(httpReq, "points_encoded", true); boolean enableInstructions = writeGPX || getBooleanParam(httpReq, "instructions", true); boolean enableElevation = getBooleanParam(httpReq, "elevation", false); boolean forceRepair = getBooleanParam(httpReq, "force_repair", false); // TODO export OSM IDs instead, use https://github.com/karussell/graphhopper-osm-id-mapping boolean enableTraversalKeys = getBooleanParam(httpReq, "traversal_keys", false); int maxNodesToVisit = (int) getLongParam(httpReq, "max_nodes_to_visit", 500); int separatedSearchDistance = (int) getLongParam(httpReq, "separated_search_distance", 300); String vehicle = getParam(httpReq, "vehicle", "car"); Locale locale = Helper.getLocale(getParam(httpReq, "locale", "en")); GHResponse matchGHRsp = new GHResponse(); MatchResult matchRsp = null; StopWatch sw = new StopWatch().start(); try { FlagEncoder encoder = hopper.getEncodingManager().getEncoder(vehicle); MapMatching matching = new MapMatching(hopper.getGraphHopperStorage(), locationIndexMatch, encoder); matching.setForceRepair(forceRepair); matching.setMaxNodesToVisit(maxNodesToVisit); matching.setSeparatedSearchDistance(separatedSearchDistance); matchRsp = matching.doWork(gpxFile.getEntries()); // fill GHResponse for identical structure Path path = matching.calcPath(matchRsp); Translation tr = trMap.getWithFallBack(locale); new PathMerger().doWork(matchGHRsp, Collections.singletonList(path), tr); } catch (Exception ex) { matchGHRsp.addError(ex); } logger.info( httpReq.getQueryString() + ", " + infoStr + ", took:" + sw.stop().getSeconds() + ", entries:" + gpxFile.getEntries().size() + ", " + matchGHRsp.getDebugInfo()); if (EXTENDED_JSON_FORMAT.equals(format)) { if (matchGHRsp.hasErrors()) { httpRes.setStatus(SC_BAD_REQUEST); httpRes.getWriter().append(new JSONArray(matchGHRsp.getErrors()).toString()); } else { httpRes.getWriter().write(new MatchResultToJson(matchRsp).exportTo().toString()); } } else if (GPX_FORMAT.equals(format)) { String xml = createGPXString(httpReq, httpRes, matchGHRsp); if (matchGHRsp.hasErrors()) { httpRes.setStatus(SC_BAD_REQUEST); httpRes.getWriter().append(xml); } else { writeResponse(httpRes, xml); } } else { Map<String, Object> map = routeSerializer.toJSON( matchGHRsp, true, pointsEncoded, enableElevation, enableInstructions); if (matchGHRsp.hasErrors()) { writeJsonError(httpRes, SC_BAD_REQUEST, new JSONObject(map)); } else { if (enableTraversalKeys) { if (matchRsp == null) { throw new IllegalStateException( "match response has to be none-null if no error happened"); } // encode edges as traversal keys which includes orientation // decode simply by multiplying with 0.5 List<Integer> traversalKeylist = new ArrayList<Integer>(); for (EdgeMatch em : matchRsp.getEdgeMatches()) { EdgeIteratorState edge = em.getEdgeState(); traversalKeylist.add( GHUtility.createEdgeKey( edge.getBaseNode(), edge.getAdjNode(), edge.getEdge(), false)); } map.put("traversal_keys", traversalKeylist); } writeJson(httpReq, httpRes, new JSONObject(map)); } } }
private GPXFile parseXML(HttpServletRequest httpReq) throws IOException { GPXFile file = new GPXFile(); return file.doImport(httpReq.getInputStream()); }