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(); }
/** * @param polygon * A simple {@link Polygon} * @return A {@link MultiPolygon} with the provided {@link Polygon} as a single outer * {@link Polygon}, with no inner {@link Polygon} */ public static MultiPolygon forPolygon(final Polygon polygon) { final MultiMap<Polygon, Polygon> multiMap = new MultiMap<>(); multiMap.put(polygon, new ArrayList<>()); return new MultiPolygon(multiMap); }
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; }
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)); }
private MultiPolygon runMultiPolygonClipping(final MultiPolygon subject, final BiFunction<Geometry, Geometry, Geometry> application) { MultiPolygon result = new MultiPolygon(new MultiMap<>()); final Set<com.vividsolutions.jts.geom.Polygon> jtsSubjects = new JtsMultiPolygonConverter() .convert(subject); for (final com.vividsolutions.jts.geom.Polygon jtsClipping : this.jtsClippings) { for (final com.vividsolutions.jts.geom.Polygon jtsSubject : jtsSubjects) { result = result .merge(processMultiPolygon(application.apply(jtsSubject, jtsClipping))); } } return result; }
return new MultiPolygon(outerToInners); };
/** * 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); }
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); } }
/** * Concatenate multiple {@link MultiPolygon}s into one. If the two {@link MultiPolygon}s happen * to have the same outer polygon, then the other's inner polygons will be added and the * current's inner polygons will be erased. * * @param other * The other {@link MultiPolygon} to concatenate. * @return The concatenated {@link MultiPolygon} */ public MultiPolygon concatenate(final MultiPolygon other) { final MultiMap<Polygon, Polygon> result = new MultiMap<>(); result.putAll(getOuterToInners()); result.putAll(other.getOuterToInners()); return new MultiPolygon(result); }
MultiPolygon multiPolygon = new MultiPolygon(new MultiMap<>()); for (final String countryCode : countries)
private MultiPolygon processMultiPolygon(final Geometry intersections) { MultiPolygon result = new MultiPolygon(new MultiMap<>()); if (intersections instanceof GeometryCollection) { final GeometryCollection collection = (GeometryCollection) intersections; final int numGeometries = collection.getNumGeometries(); for (int n = 0; n < numGeometries; n++) { final Geometry geometry = collection.getGeometryN(n); result = result.merge(processMultiPolygon(geometry)); } } else if (intersections instanceof com.vividsolutions.jts.geom.Polygon) { final Set<com.vividsolutions.jts.geom.Polygon> set = new HashSet<>(); set.add((com.vividsolutions.jts.geom.Polygon) intersections); result = result.merge(new JtsMultiPolygonConverter().backwardConvert(set)); } return result; }
final MultiPolygon allCountries = new MultiPolygon(outerToInners); final Clip clip = MultiPolygon.forPolygon(Rectangle.MAXIMUM).clip(allCountries, ClipType.NOT);
/** * Multipolygon for shard with outer smaller than the bounds */ private MultiPolygon multiPolygonForShard(final Shard shard) { final Rectangle bounds = shard.bounds(); final Rectangle outer = bounds.contract(Distance.ONE_METER); final Rectangle inner = outer.contract(Distance.ONE_METER); final MultiMap<Polygon, Polygon> multiMap = new MultiMap<>(); multiMap.put(outer, Arrays.asList(inner)); return new MultiPolygon(multiMap); }
@Override public MultiPolygon backwardConvert(final Set<com.vividsolutions.jts.geom.Polygon> object) { final MultiMap<Polygon, Polygon> result = new MultiMap<>(); for (final com.vividsolutions.jts.geom.Polygon polygon : object) { final Polygon outer = POLYGON_CONVERTER.backwardConvert(polygon); if (outer == null) { continue; } for (int n = 0; n < polygon.getNumInteriorRing(); n++) { final LinearRing ring = new LinearRing( polygon.getInteriorRingN(n).getCoordinateSequence(), FACTORY); final Polygon inner = LINEAR_RING_CONVERTER.backwardConvert(ring); result.add(outer, inner); } if (polygon.getNumInteriorRing() == 0) { // Make sure the outer still exists if the inners are not there. result.put(outer, new ArrayList<>()); } } return new MultiPolygon(result); }
@Test public void testSerialization() throws ClassNotFoundException { final MultiPolygon map = new MultiPolygon(MultiMapTest.getMultiMap()); final WritableResource out = new ByteArrayResource(); try (ObjectOutputStream outStream = new ObjectOutputStream(out.write())) { outStream.writeObject(map); } catch (final IOException e) { throw new CoreException("Unable to write to {}", out, e); } try (ObjectInputStream inStream = new ObjectInputStream(out.read())) { final MultiPolygon result = (MultiPolygon) inStream.readObject(); Assert.assertEquals(map, result); } catch (final IOException e) { throw new CoreException("Unable to read from {}", out, e); } }
@Override public MultiPolygon convert(final String object) { final MultiMap<Polygon, Polygon> result = new MultiMap<>(); final StringList outers = StringList.split(object, OUTER_SEPARATOR); for (final String outerString : outers) { final StringList outerInners = StringList.split(outerString, OUTER_INNERS_SEPARATOR); final Polygon outer = POLYGON_STRING_CONVERTER.convert(outerInners.get(0)); if (outerInners.size() > 1) { final StringList inners = StringList.split(outerInners.get(1), INNER_SEPARATOR); for (final String innerString : inners) { result.add(outer, POLYGON_STRING_CONVERTER.convert(innerString)); } } else { result.put(outer, new ArrayList<>()); } } return new MultiPolygon(result); } }
@Test public void testEmptyMultiPolygon() { final MultiPolygon empty = new MultiPolygon(new MultiMap<>()); Assert.assertNull(empty.bounds()); }
/** * This function only puts the part of the multipolygon with outers intersecting with the * shard * * @param item * to add * @param collection * to add to * @param shard * shard associated with the collection * @return whether it was added successfully */ @Override protected boolean addFunction(final MultiPolygon item, final ArrayList<MultiPolygon> collection, final Shard shard) { final Rectangle shardBounds = shard.bounds(); final MultiMap<Polygon, Polygon> newMultiPolygon = new MultiMap<>(); item.outers().forEach(outer -> { if (outer.overlaps(shardBounds)) { newMultiPolygon.put(outer, item.innersOf(outer)); } }); return collection.add(new MultiPolygon(newMultiPolygon)); }
return new MultiPolygon(outerToInners);
multiPolygonMap.add(outerPolygon, innerPolygon1); multiPolygonMap.add(outerPolygon, innerPolygon2); final MultiPolygon multiPolygon1 = new MultiPolygon(multiPolygonMap);