/** * @return The {@link Segment}'s {@link Heading}. In case the segment is the same start and end * locations, then the result is empty. */ public Optional<Heading> heading() { if (this.isPoint()) { logger.warn( "Cannot compute a segment's heading when the segment is a point with same start and end {}", this.start()); return Optional.empty(); } return Optional.of(this.start().headingTo(this.end())); }
/** * @return True if this segment is exactly east west (the two latitudes are the same) */ public boolean isEastWest() { return start().hasSameLatitudeAs(end()); }
/** * @return True if this segment is exactly north south (the two longitudes are the same) */ public boolean isNorthSouth() { return start().hasSameLongitudeAs(end()); }
@Override public boolean isPoint() { return start().equals(end()); }
@Override public Distance length() { return this.start().distanceTo(this.end()); }
/** * Convenience method to gather all {@link Location}s for a list of segments. * * @param segments * target segments * @return a list of {@link Location}s for the given segments */ public static List<Location> asList(final Iterable<Segment> segments) { final List<Location> result = new ArrayList<>(); Iterables.stream(segments).forEach(segment -> { if (result.isEmpty() || !result.get(result.size() - 1).equals(segment.start())) { result.add(segment.start()); } result.add(segment.end()); }); return result; }
@Override public Segment reversed() { return new Segment(end(), start()); }
/** * For an point defined by the two surrounding segments, return the angle and location of that * point if that point is not part of a curve, and the angle between the two segments is less * than headingThreshold. * * @param beforeAngle * the segment directly before the point in question * @param afterAngle * the segment directly after the point in question * @param curvedLocations * the locations of all curved segments in the polygon * @return an empty optional if the point is part of a curve, or if the angle is greater than or * equal to headingThreshold. Otherwise, a tuple containing the location of the point * and the angle between beforeAnge and afterAngle */ private Optional<Tuple<Angle, Location>> getSpikyAngleLocation(final Segment beforeAngle, final Segment afterAngle, final Set<Location> curvedLocations) { if (!curvedLocations.contains(afterAngle.end()) && !curvedLocations.contains(beforeAngle.start())) { final Angle difference = this.getDifferenceInHeadings(beforeAngle, afterAngle.reversed(), Angle.MAXIMUM); if (difference.isLessThan(headingThreshold)) { return Optional.of(Tuple.createTuple(difference, afterAngle.start())); } } return Optional.empty(); }
protected long longitudeSpan() { return this.end().getLongitude().asDm7() - this.start().getLongitude().asDm7(); } }
locations.add(curvedSectionEnd.start()); curvedSectionIndex++; if (curvedSectionIndex >= curvedSections.size())
protected long latitudeSpan() { return this.end().getLatitude().asDm7() - this.start().getLatitude().asDm7(); }
final Segment variable = new Segment(shape.start(), origin); final double dotProduct = shape.dotProduct(variable); if (dotProduct <= 0) return new SnappedLocation(origin, shape.start(), shape); final double latitudeAsDm7 = shape.start().getLatitude().asDm7() + offsetDistance / shape.dotProductLength() * shape.latitudeSpan(); final double longitudeAsDm7 = shape.start().getLongitude().asDm7() + offsetDistance / shape.dotProductLength() * shape.longitudeSpan(); final Location snapped = new Location(Latitude.dm7(Math.round(latitudeAsDm7)),
/** * Tests if this {@link Polygon} wraps (geometrically contains) a {@link Segment} * * @param segment * The {@link Segment} to test * @return True if this {@link Polygon} wraps (geometrically contains) the provided * {@link Segment} */ public boolean fullyGeometricallyEncloses(final Segment segment) { final Set<Location> intersections = this.intersections(segment); for (final Location intersection : intersections) { if (!intersection.equals(segment.start()) && !intersection.equals(segment.end())) { // This is a non-end intersection return false; } } return this.fullyGeometricallyEncloses(segment.middle()); }
final double p0X = this.start().getLongitude().asDegrees(); final double p0Y = this.start().getLatitude().asDegrees(); final double p1X = this.end().getLongitude().asDegrees(); final double p1Y = this.end().getLatitude().asDegrees(); final double p2X = that.start().getLongitude().asDegrees(); final double p2Y = that.start().getLatitude().asDegrees(); final double p3X = that.end().getLongitude().asDegrees(); final double p3Y = that.end().getLatitude().asDegrees();
final double xAxis1 = this.start().getLongitude().asDegrees(); final double yAxis1 = this.start().getLatitude().asDegrees(); final double xAxis2 = this.end().getLongitude().asDegrees(); final double yAxis2 = this.end().getLatitude().asDegrees(); final double xAxis3 = that.start().getLongitude().asDegrees(); final double yAxis3 = that.start().getLatitude().asDegrees(); final double xAxis4 = that.end().getLongitude().asDegrees(); final double yAxis4 = that.end().getLatitude().asDegrees();