@Test public void testClosedLoop() { final Polygon polygon = Polygon.SILICON_VALLEY; final Polygon initialClosedLoop = new Polygon(polygon.closedLoop()); Assert.assertNotEquals( "Last and Last - 1 locations for the polygon should not be duplicate.", initialClosedLoop.last(), initialClosedLoop.get(initialClosedLoop.size() - 2)); final Polygon doubleClosedLoop = new Polygon(initialClosedLoop.closedLoop()); Assert.assertNotEquals("Last and Last - 1 locations for polygon should not be duplicate.", doubleClosedLoop.last(), doubleClosedLoop.get(doubleClosedLoop.size() - 2)); }
@Override public Iterable<Point> pointsWithin(final Polygon polygon) { final Iterable<Point> points = this.getPointSpatialIndex().get(polygon.bounds()); if (polygon instanceof Rectangle) { return points; } return Iterables.filter(points, point -> polygon.fullyGeometricallyEncloses(point.getLocation())); }
@Override protected double getValue(final Area area) { return area.asPolygon().surface().asKilometerSquared(); } }
public int previousVertexIndex(final int currentVertexIndex) { verifyVertexIndex(currentVertexIndex); if (currentVertexIndex == 0) { return size() - 1; } else { return currentVertexIndex - 1; } }
private boolean overlapsInternal(final PolyLine polyline, final boolean runReverseCheck) { for (final Location location : polyline) { if (fullyGeometricallyEncloses(location)) { return true; } } if (runReverseCheck && polyline instanceof Polygon && ((Polygon) polyline).overlapsInternal(this, false)) { return true; } return this.intersects(polyline); }
public Polygon asPolygon() { return new Polygon(asPolyLine()); } }
@Override public Rectangle bounds() { return this.polygon.bounds(); }
/** * 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()); }
/** * Iterate through outers of country boundary to avoid unnecessary overlap checks * * @param zoom * The zoom level of slippy tiles * @return A set of slippy tiles */ public Set<SlippyTile> tiles(final int zoom) { final Set<SlippyTile> validTiles = new HashSet<>(); for (final Polygon subBoundary : this.boundary.outers()) { final List<SlippyTile> tiles = Iterables .asList(SlippyTile.allTiles(zoom, subBoundary.bounds())); validTiles.addAll(tiles.stream().filter(tile -> subBoundary.overlaps(tile.bounds())) .collect(Collectors.toList())); } return validTiles; } }
@Test public void testFullyGeometricallyEnclosingMultiPolygon() { final MultiPolygon multiPolygon1 = MultiPolygon .wkt("MULTIPOLYGON (" + "((-10 10, 10 10, 10 -10, -10 -10, -10 10)," + "(-6 6, 6 6, 6 -6, -6 -6, -6 6)))"); final MultiPolygon multiPolygon2 = MultiPolygon.wkt("MULTIPOLYGON (" + "((-4 4, 4 4, 4 -4, -4 -4, -4 4)," + "(-3 3, 3 3, 3 -3, -3 -3, -3 3)))"); final Polygon polygon1 = Polygon.wkt("POLYGON " + "((-8 8, 8 8, 8 -8, -8 -8, -8 8))"); final Polygon polygon2 = Polygon.wkt("POLYGON " + "((-5 5, 5 5, 5 -5, -5 -5, -5 5))"); Assert.assertFalse(polygon2.fullyGeometricallyEncloses(multiPolygon1)); Assert.assertTrue(polygon1.fullyGeometricallyEncloses(multiPolygon2)); Assert.assertFalse(polygon1.fullyGeometricallyEncloses(multiPolygon1)); Assert.assertTrue(polygon2.fullyGeometricallyEncloses(multiPolygon2)); }
/** * Creates a Polygon type GeoJson Feature * * @param polygon * geometry * @return a GeoJson Feature */ public GeoJsonObject create(final Polygon polygon) { return this.create(polygon.closedLoop(), GeoJsonType.POLYGON); }
/** * @return The closed {@link Polygon}, with the end {@link Location} equal to the start * {@link Location}. */ public Polygon getClosedGeometry() { return new Polygon(asPolygon().closedLoop()); }
/** * The segments that belong to this {@link Polygon} that are attached to this vertex * * @param vertexIndex * the index of the vertex * @return The segments that belong to this {@link Polygon} that are attached to this vertex */ public List<Segment> attachedSegments(final int vertexIndex) { verifyVertexIndex(vertexIndex); final List<Segment> result = new ArrayList<>(); // Previous if (vertexIndex > 0) { result.add(segmentForIndex(vertexIndex - 1)); } else { result.add(segmentForIndex(size() - 1)); } // Next result.add(segmentForIndex(vertexIndex)); return result; }
@Test public void testCovers() { final Rectangle rwac = Rectangle .forLocations(Iterables.iterable(Location.TEST_3, Location.TEST_1)); logger.info("Polygon: " + this.quadrant); final boolean containsTest6 = this.quadrant.fullyGeometricallyEncloses(Location.TEST_6); final boolean containsTest5 = this.quadrant.fullyGeometricallyEncloses(Location.TEST_5); final boolean containsTestRectangle = this.quadrant .fullyGeometricallyEncloses(Rectangle.TEST_RECTANGLE_2); final boolean containsRWAC = this.quadrant.fullyGeometricallyEncloses(rwac); logger.info("Test 6: {} -> {}", Location.TEST_6, containsTest6); logger.info("Test 5: {} -> {}", Location.TEST_5, containsTest5); logger.info("Test Rectangle: {} -> {}", Rectangle.TEST_RECTANGLE_2, containsTestRectangle); logger.info("RWAC 2: {} -> {}", rwac, containsRWAC); Assert.assertTrue(!containsTest5); Assert.assertTrue(containsTest6); Assert.assertTrue(containsTestRectangle); Assert.assertTrue(!containsRWAC); }
/** * Remove a vertex * * @param index * The index of the vertex to remove * @return The new {@link Polygon} without the specified vertex */ public Polygon withoutVertex(final int index) { if (index < 0 || index >= this.size()) { throw new CoreException("{} is not a vertex index of {}", index, this); } final List<Location> vertices = Iterables.asList(this); vertices.remove(index); return new Polygon(vertices); }
@Test public void testIntersects() { final Set<Location> intersection = this.quadrant.intersections(new Segment(Location.TEST_5, new Location(Location.TEST_3.getLatitude(), Location.TEST_5.getLongitude()))); Assert.assertEquals(2, intersection.size()); final Set<Location> intersections = this.quadrant.intersections(this.rectangle); Assert.assertEquals(3, intersections.size()); Assert.assertTrue(this.quadrant.intersects(this.rectangle)); }
public boolean covers(final Rectangle bound) { boolean covers = false; for (final Polygon outer : this.boundary.outers()) { if (outer.fullyGeometricallyEncloses(bound)) { covers = true; break; } if (outer.overlaps(bound)) { covers = true; break; } } return covers; }
@Test public void testPolygonWith45DegreeZeroAreaPartContains() { // Shape is a triangle, with a zero area line protruding from one of the corners on an // incline final Polygon polygon = Polygon.wkt("POLYGON ((-0.0065127 0.0214697, -0.0092975 0.0054797," + " -0.0233112 -0.0085339, 0.0027398 0.0175171, -0.0065127 0.0214697))"); final Location middleZeroAreaPart = polygon.segmentForIndex(1).middle(); final Location endpointZeroAreaPart = polygon.segmentForIndex(1).end(); final Location middleThirdSegment = polygon.segmentForIndex(2).middle(); // Locations on the zero area part are still on the boundary, and therefore contained Assert.assertTrue(polygon.fullyGeometricallyEncloses(middleZeroAreaPart)); // see awt definition of contains Assert.assertFalse(polygon.fullyGeometricallyEncloses(endpointZeroAreaPart)); Assert.assertTrue(polygon.fullyGeometricallyEncloses(middleThirdSegment)); }