@Test public void testGetAllEdgesWithDelete() { graph = createGraph(); NodeAccess na = graph.getNodeAccess(); na.setNode(0, 0, 5); na.setNode(1, 1, 5); na.setNode(2, 2, 5); na.setNode(3, 3, 5); graph.edge(0, 1, 1, true); graph.edge(0, 2, 1, true); graph.edge(1, 2, 1, true); graph.edge(2, 3, 1, true); AllEdgesIterator iter = graph.getAllEdges(); assertEquals(4, GHUtility.count(iter)); assertEquals(4, iter.getMaxId()); // delete graph.markNodeRemoved(1); graph.optimize(); iter = graph.getAllEdges(); assertEquals(2, GHUtility.count(iter)); assertEquals(4, iter.getMaxId()); iter = graph.getAllEdges(); iter.next(); EdgeIteratorState eState = iter.detach(false); assertEquals(iter.toString(), eState.toString()); iter.next(); assertNotEquals(iter.toString(), eState.toString()); EdgeIteratorState eState2 = iter.detach(true); assertEquals(iter.getAdjNode(), eState2.getBaseNode()); iter.next(); assertNotEquals(iter.getAdjNode(), eState2.getBaseNode()); }
@Test public void internalDisconnect() { GraphHopperStorage storage = createGHStorage(); BaseGraph graph = (BaseGraph) storage.getGraph(Graph.class); EdgeIteratorState iter0 = graph.edge(0, 1, 10, true); EdgeIteratorState iter2 = graph.edge(1, 2, 10, true); EdgeIteratorState iter3 = graph.edge(0, 3, 10, true); EdgeExplorer explorer = graph.createEdgeExplorer(); assertEquals(GHUtility.asSet(3, 1), GHUtility.getNeighbors(explorer.setBaseNode(0))); assertEquals(GHUtility.asSet(2, 0), GHUtility.getNeighbors(explorer.setBaseNode(1))); // remove edge "1-2" but only from 1 not from 2 graph.edgeAccess.internalEdgeDisconnect( iter2.getEdge(), -1, iter2.getBaseNode(), iter2.getAdjNode()); assertEquals(GHUtility.asSet(0), GHUtility.getNeighbors(explorer.setBaseNode(1))); assertEquals(GHUtility.asSet(1), GHUtility.getNeighbors(explorer.setBaseNode(2))); // let 0 unchanged -> no side effects assertEquals(GHUtility.asSet(3, 1), GHUtility.getNeighbors(explorer.setBaseNode(0))); // remove edge "0-1" but only from 0 graph.edgeAccess.internalEdgeDisconnect( iter0.getEdge(), (long) iter3.getEdge() * graph.edgeEntryBytes, iter0.getBaseNode(), iter0.getAdjNode()); assertEquals(GHUtility.asSet(3), GHUtility.getNeighbors(explorer.setBaseNode(0))); assertEquals(GHUtility.asSet(0), GHUtility.getNeighbors(explorer.setBaseNode(3))); assertEquals(GHUtility.asSet(0), GHUtility.getNeighbors(explorer.setBaseNode(1))); storage.close(); }
@Test public void testEdgeReturn() { graph = createGraph(); EdgeIteratorState iter = graph.edge(4, 10).setDistance(100).setFlags(carEncoder.setProperties(10, true, false)); assertEquals(4, iter.getBaseNode()); assertEquals(10, iter.getAdjNode()); iter = graph.edge(14, 10).setDistance(100).setFlags(carEncoder.setProperties(10, true, false)); assertEquals(14, iter.getBaseNode()); assertEquals(10, iter.getAdjNode()); }
@Test public void testDetachEdge() { graph = createGraph(); graph.edge(0, 1, 2, true); long flags = carEncoder.setProperties(10, true, false); graph.edge(0, 2, 2, true).setWayGeometry(Helper.createPointList(1, 2, 3, 4)).setFlags(flags); graph.edge(1, 2, 2, true); EdgeIterator iter = graph.createEdgeExplorer().setBaseNode(0); try { // currently not possible to detach without next, without introducing a new property inside // EdgeIterable iter.detach(false); assertTrue(false); } catch (Exception ex) { } iter.next(); EdgeIteratorState edgeState2 = iter.detach(false); assertEquals(2, iter.getAdjNode()); assertEquals(1, edgeState2.fetchWayGeometry(0).getLatitude(0), 1e-1); assertEquals(2, edgeState2.getAdjNode()); assertTrue(carEncoder.isBool(edgeState2.getFlags(), FlagEncoder.K_FORWARD)); EdgeIteratorState edgeState3 = iter.detach(true); assertEquals(0, edgeState3.getAdjNode()); assertEquals(2, edgeState3.getBaseNode()); assertEquals(3, edgeState3.fetchWayGeometry(0).getLatitude(0), 1e-1); assertFalse(carEncoder.isBool(edgeState3.getFlags(), FlagEncoder.K_FORWARD)); assertEquals(GHUtility.getEdge(graph, 0, 2).getFlags(), edgeState2.getFlags()); assertEquals(GHUtility.getEdge(graph, 2, 0).getFlags(), edgeState3.getFlags()); iter.next(); assertEquals(1, iter.getAdjNode()); assertEquals(2, edgeState2.getAdjNode()); assertEquals(2, edgeState3.getBaseNode()); assertEquals(0, iter.fetchWayGeometry(0).size()); assertEquals(1, edgeState2.fetchWayGeometry(0).getLatitude(0), 1e-1); assertEquals(3, edgeState3.fetchWayGeometry(0).getLatitude(0), 1e-1); // #162 a directed self referencing edge should be able to reverse its state too graph.edge(3, 3, 2, true).setFlags(flags); EdgeIterator iter2 = graph.createEdgeExplorer().setBaseNode(3); iter2.next(); assertEquals(edgeState2.getFlags(), iter2.detach(false).getFlags()); assertEquals(edgeState3.getFlags(), iter2.detach(true).getFlags()); }
@Test public void testCreateDuplicateEdges() { graph = createGraph(); graph.edge(2, 1, 12, true); graph.edge(2, 3, 12, true); graph.edge(2, 3, 13, false); assertEquals(3, GHUtility.count(carOutExplorer.setBaseNode(2))); // no exception graph.getEdgeProps(1, 3); // raise exception try { graph.getEdgeProps(4, 3); assertTrue(false); } catch (Exception ex) { } try { graph.getEdgeProps(-1, 3); assertTrue(false); } catch (Exception ex) { } EdgeIterator iter = carOutExplorer.setBaseNode(2); assertTrue(iter.next()); EdgeIteratorState oneIter = graph.getEdgeProps(iter.getEdge(), 3); assertEquals(13, oneIter.getDistance(), 1e-6); assertEquals(2, oneIter.getBaseNode()); assertTrue(carEncoder.isBool(oneIter.getFlags(), FlagEncoder.K_FORWARD)); assertFalse(carEncoder.isBool(oneIter.getFlags(), FlagEncoder.K_BACKWARD)); oneIter = graph.getEdgeProps(iter.getEdge(), 2); assertEquals(13, oneIter.getDistance(), 1e-6); assertEquals(3, oneIter.getBaseNode()); assertFalse(carEncoder.isBool(oneIter.getFlags(), FlagEncoder.K_FORWARD)); assertTrue(carEncoder.isBool(oneIter.getFlags(), FlagEncoder.K_BACKWARD)); graph.edge(3, 2, 14, true); assertEquals(4, GHUtility.count(carOutExplorer.setBaseNode(2))); }
@Test public void testEdgeProperties() { graph = createGraph(); EdgeIteratorState iter1 = graph.edge(0, 1, 10, true); EdgeIteratorState iter2 = graph.edge(0, 2, 20, true); int edgeId = iter1.getEdge(); EdgeIteratorState iter = graph.getEdgeProps(edgeId, 0); assertEquals(10, iter.getDistance(), 1e-5); edgeId = iter2.getEdge(); iter = graph.getEdgeProps(edgeId, 0); assertEquals(2, iter.getBaseNode()); assertEquals(0, iter.getAdjNode()); assertEquals(20, iter.getDistance(), 1e-5); iter = graph.getEdgeProps(edgeId, 2); assertEquals(0, iter.getBaseNode()); assertEquals(2, iter.getAdjNode()); assertEquals(20, iter.getDistance(), 1e-5); iter = graph.getEdgeProps(edgeId, Integer.MIN_VALUE); assertFalse(iter == null); assertEquals(0, iter.getBaseNode()); assertEquals(2, iter.getAdjNode()); iter = graph.getEdgeProps(edgeId, 1); assertTrue(iter == null); // delete graph.markNodeRemoved(1); graph.optimize(); // throw exception if accessing deleted edge try { graph.getEdgeProps(iter1.getEdge(), -1); assertTrue(false); } catch (Exception ex) { } }
@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)); } } }