/** * Constructs an {@link AtlasDataSource} with bounding box. Only {@link Atlas} data within the * bounding box will be loaded * * @param sparkContext * spark context as key-value pairs to use as context * @param configuration * the {@link Configuration} * @param boundingBox * a {@link Rectangle} boundary */ public AtlasDataSource(final Map<String, String> sparkContext, final Configuration configuration, final Rectangle boundingBox) { this(sparkContext, configuration, MultiPolygon.forPolygon(boundingBox)); }
if (fullyGeometricallyEncloses(location)) for (final Polygon outer : this.outers()) for (final Polygon inner : this.innersOf(outer)) return this.intersects(polyLine);
public void removeOuter(final Polygon outerToRemove) { final MultiMap<Polygon, Polygon> outersToInners = new MultiMap<>(); this.outline.outers().forEach(outer -> { final List<Polygon> innersForThisOuter = this.outline.innersOf(outer); outersToInners.put(outer, innersForThisOuter); }); outersToInners.remove(outerToRemove); setOutline(new MultiPolygon(outersToInners)); }
/** * Merge multiple {@link MultiPolygon}s into one. If the two {@link MultiPolygon}s happen to * have the same outer polygon, then the two's inner polygons will be added to the same list. * * @param other * The other {@link MultiPolygon} to merge. * @return The concatenated {@link MultiPolygon} */ public MultiPolygon merge(final MultiPolygon other) { final MultiMap<Polygon, Polygon> result = new MultiMap<>(); result.putAll(getOuterToInners()); result.addAll(other.getOuterToInners()); return new MultiPolygon(result); }
final MultiPolygon multiPolygon = tuple.getSecond(); resultMap.put(countryName, multiPolygon); for (final Polygon outer : multiPolygon.outers()) for (final Polygon inner : multiPolygon.innersOf(outer)) final MultiPolygon allCountries = new MultiPolygon(outerToInners); final Clip clip = MultiPolygon.forPolygon(Rectangle.MAXIMUM).clip(allCountries, ClipType.NOT); final MultiPolygon result = clip.getClipMultiPolygon();
private MultiPolygon runPolygonClipping(final Polygon subject, final BiFunction<Geometry, Geometry, Geometry> application) { MultiPolygon result = new MultiPolygon(new MultiMap<>()); for (final com.vividsolutions.jts.geom.Polygon jtsClipping : this.jtsClippings) { result = result.merge(processMultiPolygon( application.apply(PolygonClipper.getJts(subject), jtsClipping))); } return result; }
@Test public void testEmptyClip() { final Polygon outer = Polygon.wkt( "POLYGON ((-122.05576 37.332439, -122.009566 37.36531, -122.031007 37.390535, -122.05576 37.332439))"); final MultiPolygon clipping = MultiPolygon.forPolygon(outer); final MultiPolygon clipped = SUBJECT_MULTIPOLYGON.clip(clipping, ClipType.AND) .getClipMultiPolygon(); Assert.assertTrue(clipped.isEmpty()); }
.wkt("MULTIPOLYGON (" + "((-10 10, 10 10, 10 -10, -10 -10, -10 10)," + "(-5 5, 5 5, 5 -5, -5 -5, -5 5)))"); final MultiPolygon multiPolygon2 = MultiPolygon.wkt("MULTIPOLYGON (" + "((-8 8, 8 8, 8 -8, -8 -8, -8 8)," + "(-6 6, 6 6, 6 -6, -6 -6, -6 6)))"); final MultiPolygon multiPolygon3 = MultiPolygon.wkt("MULTIPOLYGON (" + "((-8 8, 8 8, 8 -8, -8 -8, -8 8)," + "(-4 4, 4 4, 4 -4, -4 -4, -4 4)))"); final MultiPolygon multiPolygon4 = MultiPolygon .wkt("MULTIPOLYGON (" + "((-8 8, 8 8, 8 -8, -8 -8, -8 8)))"); final MultiPolygon multiPolygon5 = MultiPolygon.wkt("MULTIPOLYGON (" + "((-4 4, 4 4, 4 -4, -4 -4, -4 4)," + "(-3 3, 3 3, 3 -3, -3 -3, -3 3)))"); final MultiPolygon multiPolygon6 = MultiPolygon .wkt("MULTIPOLYGON (" + "((8 9, 9 9, 9 8, 8 8, 8 9)," + "(8.25 8.75, 8.75 8.75, 8.75 8.25, 8.25 8.25, 8.25 8.75)))"); final MultiPolygon multiPolygon7 = MultiPolygon .wkt("MULTIPOLYGON (" + "((89 90, 90 90, 90 89, 89 89, 89 90)," + "(89.25 89.75, 89.75 89.75, 89.75 89.25, 89.25 89.25, 89.25 89.75)))"); Assert.assertTrue(multiPolygon1.fullyGeometricallyEncloses(multiPolygon2)); Assert.assertFalse(multiPolygon2.fullyGeometricallyEncloses(multiPolygon1)); Assert.assertFalse(multiPolygon1.fullyGeometricallyEncloses(multiPolygon3)); Assert.assertFalse(multiPolygon1.fullyGeometricallyEncloses(multiPolygon4)); Assert.assertFalse(multiPolygon1.fullyGeometricallyEncloses(multiPolygon5)); Assert.assertFalse(multiPolygon5.fullyGeometricallyEncloses(multiPolygon1)); Assert.assertFalse( multiPolygon1.fullyGeometricallyEncloses(multiPolygon2.merge(multiPolygon5))); Assert.assertTrue(multiPolygon1.fullyGeometricallyEncloses(multiPolygon6)); Assert.assertFalse(multiPolygon1.fullyGeometricallyEncloses(multiPolygon7)); Assert.assertFalse(multiPolygon1.fullyGeometricallyEncloses(polyLine1));
private boolean locationItemCoversInitialShardBounds(final LocationItem locationItem) { return this.policy.getInitialShardsBounds() .fullyGeometricallyEncloses(locationItem.getLocation()); }
@Override public boolean multiPolygonEntityIntersecting(final MultiPolygon multiPolygon, final AtlasEntity entity) { if (entity instanceof LineItem) { return multiPolygon.overlaps(((LineItem) entity).asPolyLine()); } if (entity instanceof LocationItem) { return multiPolygon .fullyGeometricallyEncloses(((LocationItem) entity).getLocation()); } if (entity instanceof Area) { return multiPolygon.overlaps(((Area) entity).asPolygon()); } if (entity instanceof Relation) { return ((Relation) entity).members().stream().map(RelationMember::getEntity) .anyMatch(relationEntity -> this .multiPolygonEntityIntersecting(multiPolygon, relationEntity)); } else { return false; } }
public MultiPolygon getInitialShardsBounds() { if (this.shapeCoveringInitialShards.isPresent()) { return this.shapeCoveringInitialShards.get(); } final MultiMap<Polygon, Polygon> outerToInners = new MultiMap<>(); this.initialShards.forEach(shard -> outerToInners.put(shard.bounds(), new ArrayList<>())); this.shapeCoveringInitialShards = Optional.of(new MultiPolygon(outerToInners)); return this.shapeCoveringInitialShards.get(); }
return new MultiPolygon(outerToInners); return MultiPolygon.forPolygon(((Area) entity).asPolygon());
@Test public void testSurface() { final Rectangle rectangle = Rectangle.TEST_RECTANGLE; Assert.assertEquals(rectangle.surface(), MultiPolygon.forPolygon(rectangle).surface()); final MultiPolygon tilted = MultiPolygon.forPolygon(new Polygon(rectangle.lowerLeft(), new Location(rectangle.upperLeft().getLatitude(), Longitude.degrees(rectangle.upperLeft().getLongitude().asDegrees() + 0.1)), new Location(rectangle.upperRight().getLatitude(), Longitude.degrees(rectangle.upperRight().getLongitude().asDegrees() + 0.1)), rectangle.lowerRight())); Assert.assertEquals(rectangle.surface(), tilted.surface()); }
private void populateGeometry() { final AtlasEntity source = getSource(); if (source instanceof Relation) { final Relation relation = (Relation) source; final String type = relation.tag(RelationTypeTag.KEY); if (RelationTypeTag.MULTIPOLYGON_TYPE.equals(type)) { final MultiPolygon multiPolygon = RELATION_OR_AREA_TO_MULTI_POLYGON_CONVERTER .convert(relation); // All the inland islands are inner polygons within the outer water boundaries final MultiMap<Polygon, Polygon> outerToInners = new MultiMap<>(); for (final Polygon inner : multiPolygon.inners()) { outerToInners.put(inner, new ArrayList<Polygon>()); } this.multiPolygon = new MultiPolygon(outerToInners); return; } } throw new CoreException("Geometry is not set for {}", source); } }
private void process(final CountryBoundary item) { this.sharding.shards(item.getBoundary().bounds()).forEach(shard -> { final String country = item.getCountryName(); // Skip a shard if // - there is no corresponding grid for given country // - or given country boundary doesn't overlap with shard bounds final Rectangle shardBounds = shard.bounds(); if (this.boundaryMap.countryCodesOverlappingWith(shardBounds).contains(country) && item.getBoundary().overlaps(shardBounds)) { final Set<Shard> shards = this.countryToShardMap.get(country); synchronized (shards) { shards.add(shard); } } }); } }
@Test public void testEmptyMultiPolygon() { final MultiPolygon empty = new MultiPolygon(new MultiMap<>()); Assert.assertNull(empty.bounds()); }
@Test public void testCoversPolyLine() { final MultiPolygon multiPolygon = MultiPolygon .wkt("MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40))," + "((20 35, 10 30, 10 10, 30 5, 45 20, 20 35)," + "(30 20, 20 15, 20 25, 30 20)))"); final PolyLine nonCoveredLine = new PolyLine(Location.forString("19.507134, 23.999584"), Location.forString("32.062144, 32.049430")); Assert.assertFalse(multiPolygon.fullyGeometricallyEncloses(nonCoveredLine)); final PolyLine coveredLine = new PolyLine(Location.forString("32.095270, 19.955880"), Location.forString("22.175213, 36.610574")); Assert.assertTrue(multiPolygon.fullyGeometricallyEncloses(coveredLine)); final PolyLine outside = PolyLine.TEST_POLYLINE; Assert.assertFalse(multiPolygon.fullyGeometricallyEncloses(outside)); final PolyLine jumpyLine = new PolyLine(Location.forString("32.095270, 19.955880"), Location.forString("39.927387, 32.842205")); Assert.assertFalse(multiPolygon.fullyGeometricallyEncloses(jumpyLine)); }