private static OGCConcreteGeometryCollection readGeometryCollection(BasicSliceInput input, Slice inputSlice) { // GeometryCollection: geometryType|len-of-shape1|bytes-of-shape1|len-of-shape2|bytes-of-shape2... List<OGCGeometry> geometries = new ArrayList<>(); while (input.available() > 0) { int length = input.readInt() - 1; GeometrySerializationType type = GeometrySerializationType.getForCode(input.readByte()); geometries.add(readGeometry(input, inputSlice, type, length)); } return new OGCConcreteGeometryCollection(geometries, null); }
return serialize(outputs.get(0)); return serialize(new OGCConcreteGeometryCollection(outputs, null).flattenAndRemoveOverlaps().reduceFromMulti());
private static Iterable<OGCGeometry> flattenCollection(OGCGeometry geometry) { if (geometry == null) { return ImmutableList.of(); } if (!(geometry instanceof OGCConcreteGeometryCollection)) { return ImmutableList.of(geometry); } if (((OGCConcreteGeometryCollection) geometry).numGeometries() == 0) { return ImmutableList.of(); } return () -> new GeometryCollectionIterator(geometry); }
@Override public OGCGeometry intersection(OGCGeometry another) { if (isEmpty() || another.isEmpty()) { return new OGCConcreteGeometryCollection(esriSR); } List<Geometry> geometries = toList(prepare_for_ops_(toGeometryCollection(this))); List<Geometry> otherGeometries = toList(prepare_for_ops_(toGeometryCollection(another))); List<OGCGeometry> result = new ArrayList<OGCGeometry>(); for (Geometry geometry : geometries) { for (Geometry otherGeometry : otherGeometries) { GeometryCursor intersectionCursor = OperatorIntersection.local().execute(new SimpleGeometryCursor(geometry), new SimpleGeometryCursor(otherGeometry), esriSR, null, 7); OGCGeometry intersection = OGCGeometry.createFromEsriCursor(intersectionCursor, esriSR, true); if (!intersection.isEmpty()) { result.add(intersection); } } } if (result.size() == 1) { return result.get(0).reduceFromMulti(); } return new OGCConcreteGeometryCollection(result, esriSR).flattenAndRemoveOverlaps(); }
@Override public boolean disjoint(OGCGeometry another) { if (isEmpty() || another.isEmpty()) return true; if (this == another) return false; //TODO: a simple envelope test OGCConcreteGeometryCollection flattened1 = flatten(); if (flattened1.isEmpty()) return true; OGCConcreteGeometryCollection otherCol = new OGCConcreteGeometryCollection(another, esriSR); OGCConcreteGeometryCollection flattened2 = otherCol.flatten(); if (flattened2.isEmpty()) return true; for (int i = 0, n1 = flattened1.numGeometries(); i < n1; ++i) { OGCGeometry g1 = flattened1.geometryN(i); for (int j = 0, n2 = flattened2.numGeometries(); j < n2; ++j) { OGCGeometry g2 = flattened2.geometryN(j); if (!g1.disjoint(g2)) return false; } } return true; }
@Override public boolean isSimple() { for (int i = 0, n = numGeometries(); i < n; i++) if (!geometryN(i).isSimple()) return false; return true; }
/** * Fixes topological overlaps in the GeometryCollecion. * This is equivalent to union of the geometry collection elements. * * TODO "flattened" collection is supposed to contain only mutli-geometries, but this method may return single geometries * e.g. for GEOMETRYCOLLECTION (LINESTRING (...)) it returns GEOMETRYCOLLECTION (LINESTRING (...)) * and not GEOMETRYCOLLECTION (MULTILINESTRING (...)) * @return A geometry collection that is flattened and has no overlapping elements. */ public OGCConcreteGeometryCollection flattenAndRemoveOverlaps() { //flatten and crack/cluster GeometryCursor cursor = OGCStructureInternal.prepare_for_ops_(flatten().getEsriGeometryCursor(), esriSR); //make sure geometries don't overlap return new OGCConcreteGeometryCollection(removeOverlapsHelper_(toList(cursor)), esriSR); }
@Override public boolean Equals(OGCGeometry another) { if (this == another) return !isEmpty(); OGCGeometry g1 = reduceFromMulti(); String t1 = g1.geometryType(); OGCGeometry g2 = reduceFromMulti(); if (t1 != g2.geometryType()) { return false; gc1 = gc1.flattenAndRemoveOverlaps(); gc2 = gc2.flattenAndRemoveOverlaps(); int n = gc1.numGeometries(); if (n != gc2.numGeometries()) { return false; if (!gc1.geometryN(i).Equals(gc2.geometryN(i))) { return false;
if (isFlattened()) { return this; ArrayList<Geometry> polygons = null; OGCMultiLineString polyline = null; GeometryCursor gc = getEsriGeometryCursor(); for (Geometry g = gc.next(); g != null; g = gc.next()) { if (g.isEmpty()) return new OGCConcreteGeometryCollection(list, esriSR);
public boolean contains(OGCGeometry another) { if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) { return new OGCConcreteGeometryCollection(this, esriSR).contains(another); } com.esri.core.geometry.Geometry geom1 = getEsriGeometry(); com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry(); return com.esri.core.geometry.GeometryEngine.contains(geom1, geom2, getEsriSpatialReference()); }
public OGCGeometry difference(OGCGeometry another) { if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) { return (new OGCConcreteGeometryCollection(this, esriSR)).difference(another); } com.esri.core.geometry.Geometry geom1 = getEsriGeometry(); com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry(); return createFromEsriGeometry( com.esri.core.geometry.GeometryEngine.difference(geom1, geom2, getEsriSpatialReference()), esriSR); }
public OGCGeometry intersection(OGCGeometry another) { if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) { return (new OGCConcreteGeometryCollection(this, esriSR)).intersection(another); } com.esri.core.geometry.OperatorIntersection op = (OperatorIntersection) OperatorFactoryLocal .getInstance().getOperator(Operator.Type.Intersection); com.esri.core.geometry.GeometryCursor cursor = op.execute( getEsriGeometryCursor(), another.getEsriGeometryCursor(), getEsriSpatialReference(), null, 7); return OGCGeometry.createFromEsriCursor(cursor, esriSR, true); }
@Override public String asText() { StringBuilder sb = new StringBuilder("GEOMETRYCOLLECTION "); if (is3D()) { sb.append('Z'); } if (isMeasured()) { sb.append('M'); } if (is3D() || isMeasured()) sb.append(' '); int n = numGeometries(); if (n == 0) { sb.append("EMPTY"); return sb.toString(); } sb.append('('); for (int i = 0; i < n; i++) { if (i > 0) sb.append(", "); sb.append(geometryN(i).asText()); } sb.append(')'); return sb.toString(); }
@Override public double distance(OGCGeometry another) { if (this == another) return isEmpty() ? Double.NaN : 0; double minD = Double.NaN; for (int i = 0, n = numGeometries(); i < n; ++i) { // TODO Skip expensive distance computation if bounding boxes are further away than minD double d = geometryN(i).distance(another); if (d < minD || Double.isNaN(minD)) { minD = d; // TODO Replace zero with tolerance defined by the spatial reference if (minD == 0) { break; } } } return minD; }
@Override public String asGeoJson() { return asGeoJsonImpl(GeoJsonExportFlags.geoJsonExportDefaults); }
@Override public OGCGeometry intersection(OGCGeometry another) { if (isEmpty() || another.isEmpty()) { return new OGCConcreteGeometryCollection(esriSR); } List<Geometry> geometries = toList(prepare_for_ops_(toGeometryCollection(this))); List<Geometry> otherGeometries = toList(prepare_for_ops_(toGeometryCollection(another))); List<OGCGeometry> result = new ArrayList<OGCGeometry>(); for (Geometry geometry : geometries) { for (Geometry otherGeometry : otherGeometries) { GeometryCursor intersectionCursor = OperatorIntersection.local().execute(new SimpleGeometryCursor(geometry), new SimpleGeometryCursor(otherGeometry), esriSR, null, 7); OGCGeometry intersection = OGCGeometry.createFromEsriCursor(intersectionCursor, esriSR, true); if (!intersection.isEmpty()) { result.add(intersection); } } } if (result.size() == 1) { return result.get(0).reduceFromMulti(); } return new OGCConcreteGeometryCollection(result, esriSR).flattenAndRemoveOverlaps(); }
@Override public boolean disjoint(OGCGeometry another) { if (isEmpty() || another.isEmpty()) return true; if (this == another) return false; //TODO: a simple envelope test OGCConcreteGeometryCollection flattened1 = flatten(); if (flattened1.isEmpty()) return true; OGCConcreteGeometryCollection otherCol = new OGCConcreteGeometryCollection(another, esriSR); OGCConcreteGeometryCollection flattened2 = otherCol.flatten(); if (flattened2.isEmpty()) return true; for (int i = 0, n1 = flattened1.numGeometries(); i < n1; ++i) { OGCGeometry g1 = flattened1.geometryN(i); for (int j = 0, n2 = flattened2.numGeometries(); j < n2; ++j) { OGCGeometry g2 = flattened2.geometryN(j); if (!g1.disjoint(g2)) return false; } } return true; }
@Override public boolean isSimpleRelaxed() { for (int i = 0, n = numGeometries(); i < n; i++) if (!geometryN(i).isSimpleRelaxed()) return false; return true; }
/** * Fixes topological overlaps in the GeometryCollecion. * This is equivalent to union of the geometry collection elements. * * TODO "flattened" collection is supposed to contain only mutli-geometries, but this method may return single geometries * e.g. for GEOMETRYCOLLECTION (LINESTRING (...)) it returns GEOMETRYCOLLECTION (LINESTRING (...)) * and not GEOMETRYCOLLECTION (MULTILINESTRING (...)) * @return A geometry collection that is flattened and has no overlapping elements. */ public OGCConcreteGeometryCollection flattenAndRemoveOverlaps() { //flatten and crack/cluster GeometryCursor cursor = OGCStructureInternal.prepare_for_ops_(flatten().getEsriGeometryCursor(), esriSR); //make sure geometries don't overlap return new OGCConcreteGeometryCollection(removeOverlapsHelper_(toList(cursor)), esriSR); }
@Override public boolean Equals(OGCGeometry another) { if (this == another) return !isEmpty(); OGCGeometry g1 = reduceFromMulti(); String t1 = g1.geometryType(); OGCGeometry g2 = reduceFromMulti(); if (t1 != g2.geometryType()) { return false; gc1 = gc1.flattenAndRemoveOverlaps(); gc2 = gc2.flattenAndRemoveOverlaps(); int n = gc1.numGeometries(); if (n != gc2.numGeometries()) { return false; if (!gc1.geometryN(i).Equals(gc2.geometryN(i))) { return false;