/** * Get a {@link Rectangle} around this {@link Location} * * @param extension * The height of the 1/2 {@link Rectangle}. The height of the total {@link Rectangle} * will be twice that. Same for width. * @return The {@link Rectangle} around this {@link Location} */ public Rectangle boxAround(final Distance extension) { final Location north = this.shiftAlongGreatCircle(Heading.NORTH, extension); final Location south = this.shiftAlongGreatCircle(Heading.SOUTH, extension); final Location east = this.shiftAlongGreatCircle(Heading.EAST, extension); final Location west = this.shiftAlongGreatCircle(Heading.WEST, extension); return Rectangle.forLocations(north, south, east, west); }
/** * Expand a given distance on four directions * * @param distance * The {@link Distance} to expand * @return The expanded {@link Rectangle} */ public Rectangle expand(final Distance distance) { final Location newLowerLeft = this.lowerLeft.shiftAlongGreatCircle(Heading.SOUTH, distance) .shiftAlongGreatCircle(Heading.WEST, distance); final Location newUpperRight = this.upperRight .shiftAlongGreatCircle(Heading.NORTH, distance) .shiftAlongGreatCircle(Heading.EAST, distance); return forCorners(newLowerLeft, newUpperRight); }
/** * Expand a given distance horizontally, on both directions * * @param distance * The {@link Distance} to expand * @return The expanded {@link Rectangle} */ public Rectangle expandHorizontally(final Distance distance) { final Location newLowerLeft = this.lowerLeft.shiftAlongGreatCircle(Heading.WEST, distance); final Location newUpperRight = this.upperRight.shiftAlongGreatCircle(Heading.EAST, distance); return forCorners(newLowerLeft, newUpperRight); }
/** * Expand a given distance vertically, on both directions * * @param distance * The {@link Distance} to expand * @return The expanded {@link Rectangle} */ public Rectangle expandVertically(final Distance distance) { final Location newLowerLeft = this.lowerLeft.shiftAlongGreatCircle(Heading.SOUTH, distance); final Location newUpperRight = this.upperRight.shiftAlongGreatCircle(Heading.NORTH, distance); return forCorners(newLowerLeft, newUpperRight); }
@Override public Location offsetFromStart(final Ratio ratio) { final Optional<Heading> heading = heading(); if (heading.isPresent()) { return this.start().shiftAlongGreatCircle(heading.get(), length().scaleBy(ratio)); } return this.start(); }
@Test public void testSmallPolyLine() { final Distance distance = Distance.meters(100); final Location loc1 = Location.TEST_5; final Location loc2 = loc1.shiftAlongGreatCircle(Heading.EAST, distance); final Location loc3 = loc2.shiftAlongGreatCircle(Heading.NORTH, distance); final Location loc4 = loc3.shiftAlongGreatCircle(Heading.WEST, distance); final Location loc5 = loc4.shiftAlongGreatCircle(Heading.NORTH, distance); final PolyLine polyLine = new PolyLine(loc1, loc2, loc3, loc4, loc5); System.out.println(polyLine); final StringCompressedPolyLine compressed = new StringCompressedPolyLine(polyLine); System.out.println(compressed); final PolyLine decompressed = compressed.asPolyLine(); System.out.println(decompressed); Assert.assertEquals(polyLine, decompressed); } }
public PolyLine shiftFirstAlongGreatCircle(final Heading initialHeading, final Distance distance) { return new PolyLine(new MultiIterable<>( Iterables.from(this.first().shiftAlongGreatCircle(initialHeading, distance)), this.truncate(1, 0))); }
public PolyLine shiftLastAlongGreatCircle(final Heading initialHeading, final Distance distance) { return new PolyLine(new MultiIterable<>(this.truncate(0, 1), Iterables.from(this.last().shiftAlongGreatCircle(initialHeading, distance)))); }
final Location newLowerLeft = this.lowerLeft.shiftAlongGreatCircle(Heading.NORTH, distance) .shiftAlongGreatCircle(Heading.EAST, distance); final Location newUpperRight = this.upperRight .shiftAlongGreatCircle(Heading.SOUTH, distance) .shiftAlongGreatCircle(Heading.WEST, distance); final boolean tooShortHeight = newLowerLeft.getLatitude() .isGreaterThan(newUpperRight.getLatitude());
@Test public void testMidPointAccuracyAndSpeed() { final Location location1 = new Location(Latitude.degrees(51.127), Longitude.degrees(1.338)); final Location location2 = new Location(Latitude.degrees(50.964), Longitude.degrees(1.853)); final Time beginning = Time.now(); final Location derivedMidPoint = location1.shiftAlongGreatCircle( location1.headingTo(location2), location1.distanceTo(location2).scaleBy(Ratio.HALF)); System.out.println("Derived Duration: " + beginning.elapsedSince()); System.out.println(derivedMidPoint.toString() + "\n"); final Time beginning2 = Time.now(); final Location calculatedMidPoint = location1.midPoint(location2); System.out.println("Calculated Duration: " + beginning2.elapsedSince()); System.out.println(calculatedMidPoint.toString() + "\n"); final Time beginning3 = Time.now(); final Location calculatedLoxodromicMidPoint = location1.loxodromicMidPoint(location2); System.out.println("Calculated Loxodromic Duration: " + beginning3.elapsedSince()); System.out.println(calculatedLoxodromicMidPoint.toString() + "\n"); }
@Test public void testAlgorithm() { final Atlas atlas = new MultiAtlasTest().getAtlas(); final Location start = Location.TEST_6.shiftAlongGreatCircle(Heading.NORTH, Distance.ONE_METER); final Location end = Location.TEST_2.shiftAlongGreatCircle(Heading.EAST, Distance.ONE_METER); final Route dijkstraRoute = AStarRouter.dijkstra(atlas, this.threshold).route(start, end); System.out.println(dijkstraRoute); Assert.assertEquals( Route.forEdges(atlas.edge(9), atlas.edge(-9), atlas.edge(5), atlas.edge(6)), dijkstraRoute); final Route balancedRoute = AStarRouter.balanced(atlas, this.threshold).route(start, end); System.out.println(balancedRoute); Assert.assertEquals( Route.forEdges(atlas.edge(9), atlas.edge(-9), atlas.edge(5), atlas.edge(6)), balancedRoute); }
Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(315), Distance.meters(3)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(310), Distance.meters(6)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(305), Distance.meters(9)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(300), Distance.meters(12)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(295), Distance.meters(15)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(290), Distance.meters(18)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(285), Distance.meters(21)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(280), Distance.meters(24)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(275), Distance.meters(27)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(270), Distance.meters(30))); Assert.assertFalse(halfCircleLike.isApproximatelyNSided(1, Angle.MINIMUM));
@Test public void testIsApproximatelyNSidedTriangleLike3() { // Test another triangular like shape with several additional inner points // POLYGON ((-122.003467 37.324233, -122.0034571 37.3242374, -122.0033991 37.3242654, // -122.0033691 37.324278, -122.0035536 37.3242908, -122.0034922 37.3242511, -122.003467 // 37.324233)) final Polygon polygon = new Polygon(Location.STEVENS_CREEK, Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(61), Distance.meters(1)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(59), Distance.meters(7)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(60), Distance.meters(10)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(310), Distance.meters(10)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(312), Distance.meters(3))); Assert.assertFalse(polygon.isApproximatelyNSided(1, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(1, Angle.MAXIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(2, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(2, Angle.MAXIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(0.1))); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(0.5))); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(1))); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(2))); Assert.assertTrue(polygon.isApproximatelyNSided(3, Angle.degrees(3))); Assert.assertTrue(polygon.isApproximatelyNSided(3, Angle.degrees(30))); }
@Test public void testIsApproximatelyNSidedTriangleLike1() { // Test triangular like shape with one additional inner point // POLYGON ((-122.003467 37.324233, -122.003418 37.3242555, -122.0033691 37.324278, // -122.0035536 37.3242908, -122.003467 37.324233)) final Polygon polygon = new Polygon(Location.STEVENS_CREEK, Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(60), Distance.meters(5)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(60), Distance.meters(10)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(310), Distance.meters(10))); Assert.assertFalse(polygon.isApproximatelyNSided(1, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(1, Angle.MAXIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(2, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(2, Angle.MAXIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.MINIMUM)); Assert.assertTrue(polygon.isApproximatelyNSided(3, Angle.degrees(0.1))); Assert.assertTrue(polygon.isApproximatelyNSided(3, Angle.degrees(1))); Assert.assertTrue(polygon.isApproximatelyNSided(3, Angle.degrees(30))); }
@Test public void testMovePoint() { final Atlas atlas = this.rule.getAtlas(); final ChangeBuilder changeBuilder = new ChangeBuilder(); final Point source = atlas.point(41822000000L); final Location newLocation = source.getLocation().shiftAlongGreatCircle(Heading.NORTH, Distance.ONE_METER); changeBuilder.add(new FeatureChange(ChangeType.ADD, CompletePoint.shallowFrom(source).withLocation(newLocation))); final Change change = changeBuilder.get(); final Atlas changeAtlas = new ChangeAtlas(atlas, change); Assert.assertEquals(newLocation, changeAtlas.point(41822000000L).getLocation()); final Relation disconnectedFeatures = changeAtlas.relation(41834000000L); final Point fromRelation = (Point) Iterables.stream(disconnectedFeatures.members()) .firstMatching(member -> "tree".equals(member.getRole())).get().getEntity(); Assert.assertEquals(newLocation, fromRelation.getLocation()); }
@Test public void testIsApproximatelyNSidedTriangleLike2() { // Test another triangular like shape with one additional inner point // POLYGON ((-122.05576 37.332439, -122.055711 37.3324615, -122.055662 37.332484, // -122.0558466 37.3324968, -122.05576 37.332439)) final Polygon polygon = new Polygon(Location.STEVENS_CREEK, Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(59), Distance.meters(5)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(60), Distance.meters(10)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.degrees(310), Distance.meters(10))); Assert.assertFalse(polygon.isApproximatelyNSided(1, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(1, Angle.MAXIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(2, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(2, Angle.MAXIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(0.1))); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(0.5))); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(1))); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(2))); Assert.assertTrue(polygon.isApproximatelyNSided(3, Angle.degrees(3))); Assert.assertTrue(polygon.isApproximatelyNSided(3, Angle.degrees(30))); }
@Test public void testIsApproximatelyNSidedSquare() { // Test a square with ~90 degree heading changes // POLYGON ((-122.003467 37.324233, -122.0033539 37.324233, -122.0033539 37.3241431, // -122.003467 37.3241431, -122.003467 37.324233)) final Polygon polygon = new Polygon(Location.STEVENS_CREEK, Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.EAST, Distance.meters(10)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.EAST, Distance.meters(10)) .shiftAlongGreatCircle(Heading.SOUTH, Distance.meters(10)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.SOUTH, Distance.meters(10))); Assert.assertFalse(polygon.isApproximatelyNSided(1, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(1, Angle.MAXIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(2, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(2, Angle.MAXIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(1))); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(30))); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(60))); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(89))); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(89.99))); Assert.assertTrue(polygon.isApproximatelyNSided(3, Angle.degrees(90))); Assert.assertTrue(polygon.isApproximatelyNSided(4, Angle.MINIMUM)); Assert.assertTrue(polygon.isApproximatelyNSided(4, Angle.degrees(1))); Assert.assertTrue(polygon.isApproximatelyNSided(4, Angle.degrees(89))); Assert.assertTrue(polygon.isApproximatelyNSided(4, Angle.degrees(89.99))); Assert.assertFalse(polygon.isApproximatelyNSided(4, Angle.degrees(90))); Assert.assertFalse(polygon.isApproximatelyNSided(5, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(5, Angle.MAXIMUM)); }
@Test public void testIsApproximatelyNSidedSelfIntersectingPolygon() { // Test a self-intersecting polygon // POLYGON ((-122.003467 37.324233, -122.05576 37.332439, -121.955918 37.255731, -122.003467 // 37.324233, -122.0023361 37.324233, -122.003467 37.3251323, -122.003467 37.324233)) final Polygon polygon = new Polygon(Location.STEVENS_CREEK, Location.CROSSING_85_280, Location.CROSSING_85_17, Location.STEVENS_CREEK, Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.EAST, Distance.meters(100)), Location.STEVENS_CREEK.shiftAlongGreatCircle(Heading.NORTH, Distance.meters(100))); Assert.assertFalse(polygon.isApproximatelyNSided(1, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(1, Angle.MAXIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(2, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(2, Angle.MAXIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(1))); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.degrees(90))); Assert.assertFalse(polygon.isApproximatelyNSided(3, Angle.MAXIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(4, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(5, Angle.MINIMUM)); Assert.assertTrue(polygon.isApproximatelyNSided(6, Angle.MINIMUM)); Assert.assertFalse(polygon.isApproximatelyNSided(6, Angle.MAXIMUM)); }
final Location start = location1.shiftAlongGreatCircle(Heading.EAST, Distance.ONE_METER); final Location end = location3.shiftAlongGreatCircle(Heading.WEST, Distance.ONE_METER); Assert.assertEquals(Route.forEdges(atlas.edge(1), atlas.edge(2)), router.route(start, end));