public int getSize() { return size(); }
public boolean isEmpty() { return size() == 0; }
/** * Simplifies the <code>points</code>, from index 0 to size-1. * <p> * It is a wrapper method for {@link DouglasPeucker#simplify(PointList, int, int)}. * * @return The number removed points */ public int simplify(PointList points) { return simplify(points, 0, points.size() - 1); }
void checkOne() { if (points.size() < 1) throw new IllegalStateException("Instruction must contain at least one point " + toString()); }
public PathSimplification(PathWrapper pathWrapper, DouglasPeucker douglasPeucker, boolean enableInstructions) { this.pointList = pathWrapper.getPoints(); listsToSimplify = new ArrayList<>(); if (enableInstructions) listsToSimplify.add(pathWrapper.getInstructions()); this.pathDetails = pathWrapper.getPathDetails(); for (String name : pathDetails.keySet()) { List<PathDetail> pathDetailList = pathDetails.get(name); // If the pointList only contains one point, PathDetails have to be empty because 1 point => 0 edges if (pathDetailList.isEmpty() && pointList.size() > 1) throw new IllegalStateException("PathDetails " + name + " must not be empty"); listsToSimplify.add(pathDetailList); } this.douglasPeucker = douglasPeucker; }
private static List<Coordinate> toCoordinateArray(PointList pointList) { List<Coordinate> coordinates = new ArrayList<>(pointList.size()); for (int i = 0; i < pointList.size(); i++) { coordinates.add(pointList.getDimension() == 3 ? new Coordinate(pointList.getLon(i), pointList.getLat(i)) : new Coordinate(pointList.getLon(i), pointList.getLat(i), pointList.getEle(i))); } return coordinates; }
private void calcAscendDescend(final PathWrapper rsp, final PointList pointList) { double ascendMeters = 0; double descendMeters = 0; double lastEle = pointList.getElevation(0); for (int i = 1; i < pointList.size(); ++i) { double ele = pointList.getElevation(i); double diff = Math.abs(ele - lastEle); if (ele > lastEle) ascendMeters += diff; else descendMeters += diff; lastEle = ele; } rsp.setAscend(ascendMeters); rsp.setDescend(descendMeters); }
@Override public void next(EdgeIteratorState edge, int index, int prevEdgeId) { for (PathDetailsBuilder calc : calculators) { if (calc.isEdgeDifferentToLastEdge(edge)) { calc.endInterval(lastIndex); calc.startInterval(lastIndex); } } lastIndex += edge.fetchWayGeometry(2).size(); }
/** * @return This method returns a list of gpx entries where the time (in millis) is relative to * the first which is 0. */ public List<GPXEntry> createGPXList() { if (isEmpty()) return Collections.emptyList(); List<GPXEntry> gpxList = new ArrayList<>(); long timeOffset = 0; for (int i = 0; i < size() - 1; i++) { Instruction prevInstr = (i > 0) ? get(i - 1) : null; boolean instrIsFirst = prevInstr == null; Instruction nextInstr = get(i + 1); nextInstr.checkOne(); // current instruction does not contain last point which is equals to first point of next instruction: timeOffset = get(i).fillGPXList(gpxList, timeOffset, prevInstr, nextInstr, instrIsFirst); } Instruction lastI = get(size() - 1); if (lastI.points.size() != 1) throw new IllegalStateException("Last instruction must have exactly one point but was " + lastI.points.size()); double lastLat = lastI.getFirstLat(), lastLon = lastI.getFirstLon(), lastEle = lastI.getPoints().is3D() ? lastI.getFirstEle() : Double.NaN; gpxList.add(new GPXEntry(lastLat, lastLon, lastEle, timeOffset)); return gpxList; }
/** * This method fills the edgeIds hash with edgeIds found inside the specified geometry */ public void fillEdgeIDs(GHIntHashSet edgeIds, Geometry geometry, EdgeFilter filter) { if (geometry instanceof Point) { GHPoint point = GHPoint.create((Point) geometry); findClosestEdgeToPoint(edgeIds, point, filter); } else if (geometry instanceof LineString) { PointList pl = PointList.fromLineString((LineString) geometry); // TODO do map matching or routing int lastIdx = pl.size() - 1; if (pl.size() >= 2) { double meanLat = (pl.getLatitude(0) + pl.getLatitude(lastIdx)) / 2; double meanLon = (pl.getLongitude(0) + pl.getLongitude(lastIdx)) / 2; findClosestEdge(edgeIds, meanLat, meanLon, filter); } } else if (geometry instanceof MultiPoint) { for (Coordinate coordinate : geometry.getCoordinates()) { findClosestEdge(edgeIds, coordinate.y, coordinate.x, filter); } } }
private void updatePointsAndInstruction(EdgeIteratorState edge, PointList pl) { // skip adjNode int len = pl.size() - 1; for (int i = 0; i < len; i++) { prevInstruction.getPoints().add(pl, i); } double newDist = edge.getDistance(); prevInstruction.setDistance(newDist + prevInstruction.getDistance()); prevInstruction.setTime(weighting.calcMillis(edge, false, EdgeIterator.NO_EDGE) + prevInstruction.getTime()); }
Instruction prevInstr, Instruction nextInstr, boolean firstInstr) { checkOne(); int len = points.size(); long prevTime = time; double lat = points.getLatitude(0);
+ " distance:" + lmRsp.getBest().getDistance() + ", original: " + originalRsp.getBest().getDistance() + " time:" + round2(lmRsp.getBest().getTime() / 1000) + ", original: " + round2(originalRsp.getBest().getTime() / 1000) + " points:" + lmRsp.getBest().getPoints().size() + ", original: " + originalRsp.getBest().getPoints().size();
public double calcDistance(DistanceCalc calc) { double prevLat = Double.NaN; double prevLon = Double.NaN; double prevEle = Double.NaN; double dist = 0; for (int i = 0; i < size(); i++) { if (i > 0) { if (is3D()) dist += distCalc3D.calcDist(prevLat, prevLon, prevEle, getLat(i), getLon(i), getEle(i)); else dist += calc.calcDist(prevLat, prevLon, getLat(i), getLon(i)); } prevLat = getLat(i); prevLon = getLon(i); if (is3D()) prevEle = getEle(i); } return dist; }
@Override public boolean equals(Object obj) { if (obj == null) return false; PointList other = (PointList) obj; if (this.isEmpty() && other.isEmpty()) return true; if (this.getSize() != other.getSize() || this.is3D() != other.is3D()) return false; for (int i = 0; i < size(); i++) { if (!equalsEps(getLatitude(i), other.getLatitude(i))) return false; if (!equalsEps(getLongitude(i), other.getLongitude(i))) return false; if (this.is3D() && !equalsEps(getElevation(i), other.getElevation(i))) return false; } return true; }
@Test public void testFillVirtualEdges() { initGraph(g); g.getNodeAccess().setNode(3, 0, 1); g.edge(1, 3); final int baseNode = 1; EdgeIterator iter = g.createEdgeExplorer().setBaseNode(baseNode); iter.next(); QueryResult res1 = createLocationResult(2, 1.7, iter, 1, PILLAR); QueryGraph queryGraph = new QueryGraph(g) { @Override void fillVirtualEdges(IntObjectMap<VirtualEdgeIterator> node2Edge, int towerNode, EdgeExplorer mainExpl) { super.fillVirtualEdges(node2Edge, towerNode, mainExpl); // ignore nodes should include baseNode == 1 if (towerNode == 3) assertEquals("[3->4]", node2Edge.get(towerNode).toString()); else if (towerNode == 1) assertEquals("[1->4, 1 1-0]", node2Edge.get(towerNode).toString()); else throw new IllegalStateException("not allowed " + towerNode); } }; queryGraph.lookup(Arrays.asList(res1)); EdgeIteratorState state = GHUtility.getEdge(queryGraph, 0, 1); assertEquals(4, state.fetchWayGeometry(3).size()); // fetch virtual edge and check way geometry state = GHUtility.getEdge(queryGraph, 4, 3); assertEquals(2, state.fetchWayGeometry(3).size()); }
private void interpolateElevationsOfPillarNodes() { final EdgeIterator edge = storage.getAllEdges(); final NodeAccess nodeAccess = storage.getNodeAccess(); while (edge.next()) { if (isInterpolatableEdge(edge)) { int firstNodeId = edge.getBaseNode(); int secondNodeId = edge.getAdjNode(); double lat0 = nodeAccess.getLat(firstNodeId); double lon0 = nodeAccess.getLon(firstNodeId); double ele0 = nodeAccess.getEle(firstNodeId); double lat1 = nodeAccess.getLat(secondNodeId); double lon1 = nodeAccess.getLon(secondNodeId); double ele1 = nodeAccess.getEle(secondNodeId); final PointList pointList = edge.fetchWayGeometry(0); final int count = pointList.size(); for (int index = 0; index < count; index++) { double lat = pointList.getLat(index); double lon = pointList.getLon(index); double ele = elevationInterpolator.calculateElevationBasedOnTwoPoints(lat, lon, lat0, lon0, ele0, lat1, lon1, ele1); pointList.set(index, lat, lon, ele); } edge.setWayGeometry(pointList); } } } }
@Test public void interpolatesElevationOfPillarNodes() { PointList pl1 = new PointList(3, true); pl1.add(0, 0, 0); pl1.add(0.0005, 0.0005, 100); pl1.add(0.001, 0.001, 50); GraphElevationSmoothing.smoothElevation(pl1); assertEquals(3, pl1.size()); assertEquals(50, pl1.getElevation(1), .1); PointList pl2 = new PointList(3, true); pl2.add(0.001, 0.001, 50); pl2.add(0.0015, 0.0015, 160); pl2.add(0.0016, 0.0015, 150); pl2.add(0.0017, 0.0015, 220); pl2.add(0.002, 0.002, 20); GraphElevationSmoothing.smoothElevation(pl2); assertEquals(5, pl2.size()); assertEquals(120, pl2.getElevation(1), .1); // This is not 120 anymore, as the point at index 1 was smoothed from 160=>120 assertEquals(112, pl2.getElevation(2), .1); assertEquals(50, pl2.getEle(0), .1); }
@Test public void testSimplifyCheckPointCount() { PointList pointList = new PointList(); pointList.parse2DJSON(points1); DouglasPeucker dp = new DouglasPeucker().setMaxDistance(.5); assertEquals(32, pointList.getSize()); dp.simplify(pointList); assertEquals(20, pointList.getSize()); assertFalse(pointList.toString(), pointList.toString().contains("NaN")); pointList.clear(); pointList.parse2DJSON(points1); dp.simplify(pointList, 0, pointList.size() -1); assertEquals(20, pointList.getSize()); pointList.clear(); pointList.parse2DJSON(points1); int removed1 = dp.simplify(pointList.copy(10, 20)); pointList.clear(); pointList.parse2DJSON(points1); int removed2 = dp.simplify(pointList, 10, 19); assertEquals(removed1, removed2); }