/** * @param index * The index to query * @return The {@link Location} at the index provided in this {@link PolyLine} */ public Location get(final int index) { if (index < 0 || index >= size()) { throw new CoreException("Cannot get a Location with index " + index + ", which is not between 0 and " + size()); } return this.points.get(index); }
/** * @return The first {@link Location} of this {@link PolyLine} */ public Location first() { return size() > 0 ? get(0) : null; }
public Location last() { return this.points.size() > 0 ? get(size() - 1) : null; }
/** * @return the number of shape-points for this item, including start and end points. */ public int numberOfShapePoints() { return asPolyLine().size(); }
/** * Truncates this {@link PolyLine} at the given start and end index. If the provided indices are * invalid, an empty Iterable will be returned. * * @param indexFromStart * The index before which to truncate from the start * @param indexFromEnd * The index after which to truncate from the end * @return all the locations in this {@link PolyLine} after truncation. */ public Iterable<Location> truncate(final int indexFromStart, final int indexFromEnd) { if (indexFromStart < 0 || indexFromEnd < 0 || indexFromStart >= this.size() || indexFromEnd >= this.size() || indexFromStart + indexFromEnd >= this.size()) { logger.debug("Invalid start index {} or end index {} supplied.", indexFromStart, indexFromEnd); return Collections.emptyList(); } return Iterables.stream(this).truncate(indexFromStart, indexFromEnd); }
public PolyLine reversed() { final List<Location> reversed = new ArrayList<>(); for (int i = this.size() - 1; i >= 0; i--) { reversed.add(this.get(i)); } return new PolyLine(reversed); }
public boolean isOppositeDirectionUsingOverallHeading(final PolyLine incomingEdgePolyline, final PolyLine outgoingEdgePolyline) { boolean oppositeDirection = false; if (Math.min(incomingEdgePolyline.size(), outgoingEdgePolyline.size()) > 1) { final Optional<Heading> incomingSegmentHeading = incomingEdgePolyline.overallHeading(); final Optional<Heading> outgoingSegmentHeading = outgoingEdgePolyline.overallHeading(); if (incomingSegmentHeading.isPresent() && outgoingSegmentHeading.isPresent()) { oppositeDirection = isOppositeDirection(incomingSegmentHeading.get(), outgoingSegmentHeading.get()); } } return oppositeDirection; }
private static Segment candidateSegment(final List<PolyLine> candidates, final int polyLineIndex, final int segmentIndex) { return new Segment(candidates.get(polyLineIndex).get(segmentIndex), segmentIndex < candidates.get(polyLineIndex).size() - 1 ? candidates.get(polyLineIndex).get(segmentIndex + 1) : candidates.get(polyLineIndex).first()); }
public boolean isOppositeDirectionUsingSegmentHeading(final PolyLine incomingEdgePolyline, final PolyLine outgoingEdgePolyline) { boolean oppositeDirection = false; if (Math.min(incomingEdgePolyline.size(), outgoingEdgePolyline.size()) > 1) { final List<Segment> incomingSegments = incomingEdgePolyline.segments(); final Optional<Heading> incomingSegmentHeading = incomingSegments .get(incomingSegments.size() - 1).heading(); final Optional<Heading> outgoingSegmentHeading = outgoingEdgePolyline.segments().get(0) .heading(); if (incomingSegmentHeading.isPresent() && outgoingSegmentHeading.isPresent()) { oppositeDirection = isOppositeDirection(incomingSegmentHeading.get(), outgoingSegmentHeading.get()); } } return oppositeDirection; }
@Override public PolyLine asPolyLine() { final PolyLine one = this.upstream.asPolyLine(); final PolyLine two = this.downstream.asPolyLine(); final List<Location> points = new ArrayList<>(); one.forEach(points::add); for (int i = 1; i < two.size(); i++) { points.add(two.get(i)); } return new PolyLine(points); }
@Override protected double getValue(final Edge item) { return item.asPolyLine().size() / item.length().asKilometers(); }
if (size() == 1)
/** * Return the average distance from this {@link PolyLine}'s shape points to the other shape, * using a one-way snapping. * * @param other * The other shape to compare to * @return The one way cost distance to the other {@link PolyLine} */ public Distance averageOneWayDistanceTo(final PolyLine other) { Distance costDistance = Distance.ZERO; for (final Location shapePoint : this) { costDistance = costDistance.add(shapePoint.snapTo(other).getDistance()); } return costDistance.scaleBy(1.0 / this.size()); }
/** * @return This {@link PolyLine} as Well Known Binary */ @Override public byte[] toWkb() { if (this.size() == 1) { // Handle a single location polyLine return new WkbLocationConverter().convert(this.first()); } return new WkbPolyLineConverter().convert(this); }
/** * @return This {@link PolyLine} as Well Known Text */ @Override public String toWkt() { if (this.size() == 1) { // Handle a single location polyLine return new WktLocationConverter().convert(this.first()); } return new WktPolyLineConverter().convert(this); }
private PolyLineRoute(final PolyLine source, final List<PolyLine> candidates, final List<Segment> candidateSegments) { this.candidateSegments = candidateSegments; this.source = source; this.candidates = candidates; this.cost = this.source.averageOneWayDistanceTo(this.asPolyLine()) .add(this.asPolyLine().size() > 2 ? new PolyLine(this.asPolyLine().innerLocations()) .averageOneWayDistanceTo(this.source) : Distance.ZERO); }
@Test public void testMatch() { final PolyLine source = new PolyLine(Location.CROSSING_85_280, Location.TEST_2, Location.TEST_1); final PolyLine candidate1 = new PolyLine(Location.CROSSING_85_280, Location.TEST_2, Location.TEST_5); final PolyLine candidate2 = new PolyLine(Location.CROSSING_85_17, Location.TEST_2, Location.TEST_1); final List<PolyLine> candidates = Iterables .asList(Iterables.iterable(candidate1, candidate2)); final PolyLineRoute route = source.costDistanceToOneWay(candidates) .match(Distance.ZERO, Duration.ONE_MINUTE) .orElseThrow(() -> new CoreException("Did not find a route!")); logger.info("{}", route); Assert.assertEquals(3, route.asPolyLine().size()); } }
@Test public void allEdgesAreStraight() { final Predicate<Edge> straight = edge -> edge.asPolyLine().size() == 2; resetAndChange("allEdgesAreStraight", atlas -> { return Iterables.stream(atlas.edges()).filter(straight.negate()).map(edge -> { return CompleteEdge.shallowFrom(edge).withPolyLine( new PolyLine(edge.start().getLocation(), edge.end().getLocation())); }).map(FeatureChange::add).collectToSet(); }); final long straightEdges = Iterables.size(this.changeAtlas.edges(straight)); final long originalAtlasStraightEdges = Iterables.size(this.atlas.edges(straight)); final long subAtlasStraightEdges = Iterables.size(this.subAtlas.edges(straight)); Assert.assertEquals(428, straightEdges); Assert.assertEquals(337, originalAtlasStraightEdges); Assert.assertEquals(266, subAtlasStraightEdges); Assert.assertEquals(straightEdges - originalAtlasStraightEdges + subAtlasStraightEdges, this.subAtlas.numberOfEdges()); }