public void add(PointList points) { int newSize = size + points.getSize(); incCap(newSize); for (int i = 0; i < points.getSize(); i++) { int tmp = size + i; latitudes[tmp] = points.getLatitude(i); longitudes[tmp] = points.getLongitude(i); if (is3D) elevations[tmp] = points.getElevation(i); } size = newSize; }
@Test public void testBoth() throws Exception { PointList list = Helper.createPointList( 38.5, -120.2, 43.252, -126.453, 40.7, -120.95, 50.3139, 10.612793, 50.04303, 9.497681); String str = WebHelper.encodePolyline(list); assertEquals(list, WebHelper.decodePolyline(str, list.size())); list = Helper.createPointList(38.5, -120.2, 43.252, -126.453, 40.7, -120.95, 40.70001, -120.95001); str = WebHelper.encodePolyline(list); assertEquals(list, WebHelper.decodePolyline(str, list.size())); }
public PointList clone(boolean reverse) { PointList clonePL = new PointList(size, is3D); if (is3D) for (int i = 0; i < size; i++) { clonePL.add(latitudes[i], longitudes[i], elevations[i]); } else for (int i = 0; i < size; i++) { clonePL.add(latitudes[i], longitudes[i]); } if (reverse) clonePL.reverse(); return clonePL; }
@Override public int addEdge(TLongList osmIds, int flags) { PointList pointList = new PointList(osmIds.size()); int successfullyAdded = 0; int firstNode = -1; int lastIndex = osmIds.size() - 1; int lastInBoundsPillarNode = -1; for (int i = 0; i < osmIds.size(); i++) { long osmId = osmIds.get(i); int tmpNode = osmIdToIndexMap.get(osmId); if (tmpNode == EMPTY) continue; // skip osmIds with no associated pillar or tower id (e.g. !OSMReader.isBounds) if (tmpNode == TOWER_NODE) continue; if (tmpNode == PILLAR_NODE) { // In some cases no node information is saved for the specified osmId. // ie. a way references a <node> which does not exist in the current file. // => if the node before was a pillar node then convert into to tower node (as it is also // end-standing). if (!pointList.isEmpty() && lastInBoundsPillarNode > -TOWER_NODE) { // transform the pillar node to a tower node tmpNode = lastInBoundsPillarNode; tmpNode = handlePillarNode(tmpNode, osmId, null, true); tmpNode = -tmpNode - 3; if (pointList.size() > 1 && firstNode >= 0) { // TOWER node successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags); pointList.clear(); pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode)); } firstNode = tmpNode; lastInBoundsPillarNode = -1; } continue; } if (tmpNode <= -TOWER_NODE && tmpNode >= TOWER_NODE) throw new AssertionError("Mapped index not in correct bounds " + tmpNode + ", " + osmId); if (tmpNode > -TOWER_NODE) { boolean convertToTowerNode = i == 0 || i == lastIndex; if (!convertToTowerNode) lastInBoundsPillarNode = tmpNode; // PILLAR node, but convert to towerNode if end-standing tmpNode = handlePillarNode(tmpNode, osmId, pointList, convertToTowerNode); } if (tmpNode < TOWER_NODE) { // TOWER node tmpNode = -tmpNode - 3; pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode)); if (firstNode >= 0) { successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags); pointList.clear(); pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode)); } firstNode = tmpNode; } } return successfullyAdded; }
int addEdge(int fromIndex, int toIndex, PointList pointList, int flags) { double towerNodeDistance = 0; double prevLat = pointList.latitude(0); double prevLon = pointList.longitude(0); double lat; double lon; PointList pillarNodes = new PointList(pointList.size() - 2); int nodes = pointList.size(); for (int i = 1; i < nodes; i++) { lat = pointList.latitude(i); lon = pointList.longitude(i); towerNodeDistance += callback.calcDist(prevLat, prevLon, lat, lon); prevLat = lat; prevLon = lon; if (nodes > 2 && i < nodes - 1) pillarNodes.add(lat, lon); } if (towerNodeDistance == 0) { // As investigation shows often two paths should have crossed via one identical point // but end up in two very close points. later this will be removed/fixed while // removing short edges where one node is of degree 2 zeroCounter++; towerNodeDistance = 0.0001; } EdgeIterator iter = g.edge(fromIndex, toIndex, towerNodeDistance, flags); if (nodes > 2) iter.wayGeometry(pillarNodes); return nodes; }
@Test public void testSimpleDelete2() { graph = createGraph(); NodeAccess na = graph.getNodeAccess(); assertEquals(-1, getIdOf(graph, 12)); na.setNode(9, 9, 1); assertEquals(-1, getIdOf(graph, 12)); na.setNode(11, 11, 1); na.setNode(12, 12, 1); // mini subnetwork which gets completely removed: graph.edge(5, 10, 510, true); graph.markNodeRemoved(5); graph.markNodeRemoved(10); PointList pl = new PointList(); pl.add(1, 2, Double.NaN); pl.add(1, 3, Double.NaN); graph.edge(9, 11, 911, true).setWayGeometry(pl); graph.edge(9, 12, 912, true).setWayGeometry(pl); assertEquals(13, graph.getNodes()); assertEquals(Arrays.<String>asList(), GHUtility.getProblems(graph)); // perform deletion graph.optimize(); assertEquals(11, graph.getNodes()); assertEquals(Arrays.<String>asList(), GHUtility.getProblems(graph)); int id11 = getIdOf(graph, 11); // is now 10 int id12 = getIdOf(graph, 12); // is now 5 int id9 = getIdOf(graph, 9); // is now 9 assertEquals( GHUtility.asSet(id12, id11), GHUtility.getNeighbors(carAllExplorer.setBaseNode(id9))); assertEquals(GHUtility.asSet(id9), GHUtility.getNeighbors(carAllExplorer.setBaseNode(id11))); assertEquals(GHUtility.asSet(id9), GHUtility.getNeighbors(carAllExplorer.setBaseNode(id12))); EdgeIterator iter = carAllExplorer.setBaseNode(id9); assertTrue(iter.next()); assertEquals(id12, iter.getAdjNode()); assertEquals(2, iter.fetchWayGeometry(0).getLongitude(0), 1e-7); assertTrue(iter.next()); assertEquals(id11, iter.getAdjNode()); assertEquals(2, iter.fetchWayGeometry(0).getLongitude(0), 1e-7); }
/** @return converted tower node */ private int handlePillarNode( int tmpNode, long osmId, PointList pointList, boolean convertToTowerNode) { tmpNode = tmpNode - 3; int intlat = pillarLats.getInt(tmpNode); int intlon = pillarLons.getInt(tmpNode); if (intlat == Integer.MAX_VALUE || intlon == Integer.MAX_VALUE) throw new AssertionError( "Conversation pillarNode to towerNode already happended!? " + "osmId:" + osmId + " pillarIndex:" + tmpNode); double tmpLat = Helper.intToDegree(intlat); double tmpLon = Helper.intToDegree(intlon); if (convertToTowerNode) { // convert pillarNode type to towerNode, make pillar values invalid pillarLons.setInt(tmpNode, Integer.MAX_VALUE); pillarLats.setInt(tmpNode, Integer.MAX_VALUE); tmpNode = addTowerNode(osmId, tmpLat, tmpLon); } else pointList.add(tmpLat, tmpLon); return tmpNode; }
@Override public int addEdge(TLongList nodes, int flags) { PointList pointList = new PointList(nodes.size()); int successfullyAdded = 0; int firstNode = -1; int lastIndex = nodes.size() - 1; int lastInBoundsPillarNode = -1; for (int i = 0; i < nodes.size(); i++) { long osmId = nodes.get(i); int tmpNode = osmIdToIndexMap.get(osmId); if (tmpNode == EMPTY) continue; // skip osmIds with no associated pillar or tower id (e.g. !OSMReader.isBounds) if (tmpNode == TOWER_NODE) continue; if (tmpNode == PILLAR_NODE) { // no pillarLats,pillarLons was saved for tmpNode // so if there are any existing pillar nodes we need to create an edge out of them if (!pointList.isEmpty() && lastInBoundsPillarNode >= 3) { // transform the pillar node to a tower node tmpNode = lastInBoundsPillarNode; tmpNode = handlePillarNode(tmpNode, osmId, null, true); tmpNode = -tmpNode - 3; if (pointList.size() > 1 && firstNode >= 0) { // TOWER node successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags); pointList.clear(); pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode)); } firstNode = tmpNode; lastInBoundsPillarNode = -1; } continue; } if (tmpNode <= -TOWER_NODE && tmpNode >= TOWER_NODE) throw new AssertionError("Mapped index not in correct bounds " + tmpNode); if (tmpNode > -TOWER_NODE) { lastInBoundsPillarNode = tmpNode; // PILLAR node, but convert to towerNode if end-standing tmpNode = handlePillarNode(tmpNode, osmId, pointList, i == 0 || i == lastIndex); } if (tmpNode < TOWER_NODE) { // TOWER node tmpNode = -tmpNode - 3; pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode)); if (firstNode >= 0) { successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags); pointList.clear(); pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode)); } firstNode = tmpNode; } } return successfullyAdded; }
public static void assertPList(PointList expected, PointList list) { assertEquals("size of point lists is not equal", expected.getSize(), list.getSize()); for (int i = 0; i < expected.getSize(); i++) { assertEquals(expected.getLatitude(i), list.getLatitude(i), 1e-4); assertEquals(expected.getLongitude(i), list.getLongitude(i), 1e-4); } }
public PointList copy(int from, int end) { if (from > end) throw new IllegalArgumentException("from must be smaller or equals to end"); if (from < 0 || end > size) throw new IllegalArgumentException( "Illegal interval: " + from + ", " + end + ", size:" + size); PointList copyPL = new PointList(size, is3D); if (is3D) for (int i = from; i < end; i++) { copyPL.add(latitudes[i], longitudes[i], elevations[i]); } else for (int i = from; i < end; i++) { copyPL.add(latitudes[i], longitudes[i], Double.NaN); } return copyPL; }
@Override public boolean equals(Object obj) { if (obj == null) return false; PointList other = (PointList) obj; if (other.isEmpty() && other.isEmpty()) return true; if (this.getSize() != other.getSize() || this.is3D() != other.is3D()) return false; for (int i = 0; i < size; i++) { if (!NumHelper.equalsEps(latitudes[i], other.latitudes[i])) return false; if (!NumHelper.equalsEps(longitudes[i], other.longitudes[i])) return false; if (is3D && !NumHelper.equalsEps(elevations[i], other.elevations[i])) return false; } return true; }
public TestAlgoCollector assertDistance( AlgoHelperEntry algoEntry, List<QueryResult> queryList, OneRun oneRun) { List<Path> altPaths = new ArrayList<Path>(); QueryGraph queryGraph = new QueryGraph(algoEntry.getQueryGraph()); queryGraph.lookup(queryList); AlgorithmOptions opts = algoEntry.opts; FlagEncoder encoder = opts.getFlagEncoder(); if (encoder.supports(TurnWeighting.class)) algoEntry.setAlgorithmOptions( AlgorithmOptions.start(opts) .weighting( new TurnWeighting( opts.getWeighting(), opts.getFlagEncoder(), (TurnCostExtension) queryGraph.getExtension())) .build()); for (int i = 0; i < queryList.size() - 1; i++) { RoutingAlgorithm algo = algoEntry.createAlgo(queryGraph); Path path = algo.calcPath(queryList.get(i).getClosestNode(), queryList.get(i + 1).getClosestNode()); // System.out.println(path.calcInstructions().createGPX("temp", 0, "GMT")); altPaths.add(path); } PathMerger pathMerger = new PathMerger().setCalcPoints(true).setSimplifyResponse(false).setEnableInstructions(true); AltResponse rsp = new AltResponse(); pathMerger.doWork(rsp, altPaths, trMap.getWithFallBack(Locale.US)); if (rsp.hasErrors()) { errors.add( algoEntry + " response contains errors. Expected distance: " + rsp.getDistance() + ", expected points: " + oneRun + ". " + queryList + ", errors:" + rsp.getErrors()); return this; } PointList pointList = rsp.getPoints(); double tmpDist = pointList.calcDistance(distCalc); if (Math.abs(rsp.getDistance() - tmpDist) > 2) { errors.add( algoEntry + " path.getDistance was " + rsp.getDistance() + "\t pointList.calcDistance was " + tmpDist + "\t (expected points " + oneRun.getLocs() + ", expected distance " + oneRun.getDistance() + ") " + queryList); } if (Math.abs(rsp.getDistance() - oneRun.getDistance()) > 2) { errors.add( algoEntry + " returns path not matching the expected distance of " + oneRun.getDistance() + "\t Returned was " + rsp.getDistance() + "\t (expected points " + oneRun.getLocs() + ", was " + pointList.getSize() + ") " + queryList); } // There are real world instances where A-B-C is identical to A-C (in meter precision). if (Math.abs(pointList.getSize() - oneRun.getLocs()) > 1) { errors.add( algoEntry + " returns path not matching the expected points of " + oneRun.getLocs() + "\t Returned was " + pointList.getSize() + "\t (expected distance " + oneRun.getDistance() + ", was " + rsp.getDistance() + ") " + queryList); } return this; }
public void suggest(File locationFile, int locationListSize, File outputFile, int hubSize) { // WARNING: this code is VERY DIRTY. // It's JUST good enough to generate the hubs for Belgium once (because we only need to // determine them once). // Further research to generate good hubs is needed. List<AirLocation> locationList = readAirLocationFile(locationFile); if (locationListSize > locationList.size()) { throw new IllegalArgumentException( "The locationListSize (" + locationListSize + ") is larger than the locationList size (" + locationList.size() + ")."); } locationList = subselectLocationList(locationListSize, locationList); Map<Point, Point> fromPointMap = new LinkedHashMap<Point, Point>(locationListSize * 10); Map<Point, Point> toPointMap = new LinkedHashMap<Point, Point>(locationListSize * 10); int rowIndex = 0; double maxAirDistance = 0.0; for (AirLocation fromAirLocation : locationList) { for (AirLocation toAirLocation : locationList) { double airDistance = fromAirLocation.getAirDistanceDouble(toAirLocation); if (airDistance > maxAirDistance) { maxAirDistance = airDistance; } } } double airDistanceThreshold = maxAirDistance / 10.0; for (AirLocation fromAirLocation : locationList) { for (AirLocation toAirLocation : locationList) { double distance; if (fromAirLocation != toAirLocation) { GHRequest request = new GHRequest( fromAirLocation.getLatitude(), fromAirLocation.getLongitude(), toAirLocation.getLatitude(), toAirLocation.getLongitude()) .setVehicle("car"); GHResponse response = graphHopper.route(request); if (response.hasErrors()) { throw new IllegalStateException( "GraphHopper gave " + response.getErrors().size() + " errors. First error chained.", response.getErrors().get(0)); } // Distance should be in km, not meter distance = response.getDistance() / 1000.0; if (distance == 0.0) { throw new IllegalArgumentException( "The fromAirLocation (" + fromAirLocation + ") and toAirLocation (" + toAirLocation + ") are the same."); } PointList ghPointList = response.getPoints(); PointPart previousFromPointPart = null; PointPart previousToPointPart = null; double previousLatitude = Double.NaN; double previousLongitude = Double.NaN; for (int i = 0; i < ghPointList.size(); i++) { double latitude = ghPointList.getLatitude(i); double longitude = ghPointList.getLongitude(i); if (latitude == previousLatitude && longitude == previousLongitude) { continue; } if (calcAirDistance( latitude, longitude, fromAirLocation.getLatitude(), fromAirLocation.getLongitude()) < airDistanceThreshold) { Point fromPoint = new Point(latitude, longitude); Point oldFromPoint = fromPointMap.get(fromPoint); if (oldFromPoint == null) { // Initialize fromPoint instance fromPoint.pointPartMap = new LinkedHashMap<AirLocation, PointPart>(); fromPointMap.put(fromPoint, fromPoint); } else { // Reuse existing fromPoint instance fromPoint = oldFromPoint; } PointPart fromPointPart = fromPoint.pointPartMap.get(fromAirLocation); if (fromPointPart == null) { fromPointPart = new PointPart(fromPoint, fromAirLocation); fromPoint.pointPartMap.put(fromAirLocation, fromPointPart); fromPointPart.previousPart = previousFromPointPart; } fromPointPart.count++; previousFromPointPart = fromPointPart; } if (calcAirDistance( latitude, longitude, toAirLocation.getLatitude(), toAirLocation.getLongitude()) < airDistanceThreshold) { Point toPoint = new Point(latitude, longitude); Point oldToPoint = toPointMap.get(toPoint); if (oldToPoint == null) { // Initialize toPoint instance toPoint.pointPartMap = new LinkedHashMap<AirLocation, PointPart>(); toPointMap.put(toPoint, toPoint); } else { // Reuse existing toPoint instance toPoint = oldToPoint; } // Basically do the same as fromPointPart, but while traversing in the other direction PointPart toPointPart = toPoint.pointPartMap.get(toAirLocation); boolean newToPointPart = false; if (toPointPart == null) { toPointPart = new PointPart(toPoint, toAirLocation); toPoint.pointPartMap.put(toAirLocation, toPointPart); newToPointPart = true; } if (previousToPointPart != null) { previousToPointPart.previousPart = toPointPart; } toPointPart.count++; if (newToPointPart) { previousToPointPart = toPointPart; } else { previousToPointPart = null; } } previousLatitude = latitude; previousLongitude = longitude; } } } logger.debug(" Finished routes for rowIndex {}/{}", rowIndex, locationList.size()); rowIndex++; } Set<Point> hubPointList = new LinkedHashSet<Point>(20); extractFromHubs(new ArrayList<Point>(fromPointMap.values()), hubPointList, (hubSize + 1) / 2); extractFromHubs(new ArrayList<Point>(toPointMap.values()), hubPointList, hubSize / 2); logger.info("Writing hubs..."); BufferedWriter vrpWriter = null; try { vrpWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8")); vrpWriter.write("HUB_COORD_SECTION\n"); int id = 0; for (Point point : hubPointList) { vrpWriter.write("" + id + " " + point.latitude + " " + point.longitude + " " + id + "\n"); id++; } vrpWriter.write("\n\nGOOGLE MAPS\n"); for (Point point : hubPointList) { vrpWriter.write("" + id + "\t0\t" + point.latitude + "," + point.longitude + "\n"); id++; } } catch (IOException e) { throw new IllegalArgumentException( "Could not read the locationFile (" + locationFile.getName() + ") or write the vrpOutputFile (" + outputFile.getName() + ").", e); } finally { IOUtils.closeQuietly(vrpWriter); } // Throw in google docs spreadsheet and use add-on Mapping Sheets to visualize. }
@Override public GHResponse route(GHRequest request) { request.check(); StopWatch sw = new StopWatch().start(); GHResponse rsp = new GHResponse(); if (!setSupportsVehicle(request.getVehicle())) { rsp.addError( new IllegalArgumentException( "Vehicle " + request.getVehicle() + " unsupported. Supported are: " + getEncodingManager())); return rsp; } EdgeFilter edgeFilter = new DefaultEdgeFilter(encodingManager.getEncoder(request.getVehicle())); int from = index .findClosest(request.getFrom().lat, request.getFrom().lon, edgeFilter) .getClosestNode(); int to = index.findClosest(request.getTo().lat, request.getTo().lon, edgeFilter).getClosestNode(); String debug = "idLookup:" + sw.stop().getSeconds() + "s"; if (from < 0) rsp.addError(new IllegalArgumentException("Cannot find point 1: " + request.getFrom())); if (to < 0) rsp.addError(new IllegalArgumentException("Cannot find point 2: " + request.getTo())); if (from == to) rsp.addError(new IllegalArgumentException("Point 1 is equal to point 2")); sw = new StopWatch().start(); RoutingAlgorithm algo = null; if (chUsage) { if (request.getAlgorithm().equals("dijkstrabi")) algo = prepare.createAlgo(); else if (request.getAlgorithm().equals("astarbi")) algo = ((PrepareContractionHierarchies) prepare).createAStar(); else rsp.addError( new IllegalStateException( "Only dijkstrabi and astarbi is supported for LevelGraph (using contraction hierarchies)!")); } else { prepare = NoOpAlgorithmPreparation.createAlgoPrepare( graph, request.getAlgorithm(), encodingManager.getEncoder(request.getVehicle()), request.getType()); algo = prepare.createAlgo(); } if (rsp.hasErrors()) { return rsp; } debug += ", algoInit:" + sw.stop().getSeconds() + "s"; sw = new StopWatch().start(); Path path = algo.calcPath(from, to); debug += ", " + algo.getName() + "-routing:" + sw.stop().getSeconds() + "s" + ", " + path.getDebugInfo(); PointList points = path.calcPoints(); simplifyRequest = request.getHint("simplifyRequest", simplifyRequest); if (simplifyRequest) { sw = new StopWatch().start(); int orig = points.getSize(); double minPathPrecision = request.getHint("douglas.minprecision", 1d); if (minPathPrecision > 0) { new DouglasPeucker().setMaxDistance(minPathPrecision).simplify(points); } debug += ", simplify (" + orig + "->" + points.getSize() + "):" + sw.stop().getSeconds() + "s"; } enableInstructions = request.getHint("instructions", enableInstructions); if (enableInstructions) { sw = new StopWatch().start(); rsp.setInstructions(path.calcInstructions()); debug += ", instructions:" + sw.stop().getSeconds() + "s"; } return rsp.setPoints(points) .setDistance(path.getDistance()) .setTime(path.getTime()) .setDebugInfo(debug); }
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; }
@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); } }