Class ShapeCollection<S extends Shape>

java.lang.Object
java.util.AbstractCollection<S>
java.util.AbstractList<S>
org.locationtech.spatial4j.shape.ShapeCollection<S>
All Implemented Interfaces:
Iterable<S>, Collection<S>, List<S>, SequencedCollection<S>, Shape

public class ShapeCollection<S extends Shape> extends AbstractList<S> implements Shape
A collection of Shape objects, analogous to an OGC GeometryCollection. The implementation demands a List (with random access) so that the order can be retained if an application requires it, although logically it's treated as an unordered Set, mostly.

Ideally, relate(Shape) should return the same result no matter what the shape order is, although the default implementation can be order dependent when the shapes overlap; see relateContainsShortCircuits(). To improve performance slightly, the caller could order the shapes by largest first so that relate() will have a greater chance of short-circuit'ing sooner. As the Shape contract states; it may return intersects when the best answer is actually contains or within. If any shape intersects the provided shape then that is the answer.

This implementation is not optimized for a large number of shapes; relate is O(N). A more sophisticated implementation might do an R-Tree based on bbox'es, for example.

  • Field Details

  • Constructor Details

    • ShapeCollection

      public ShapeCollection(List<S> shapes, SpatialContext ctx)
      WARNING: shapes is copied by reference.
      Parameters:
      shapes - Copied by reference! (make a defensive copy if caller modifies)
  • Method Details

    • computeBoundingBox

      protected Rectangle computeBoundingBox(Collection<? extends Shape> shapes, SpatialContext ctx)
    • getShapes

      public List<S> getShapes()
    • get

      public S get(int index)
      Specified by:
      get in interface List<S extends Shape>
      Specified by:
      get in class AbstractList<S extends Shape>
    • size

      public int size()
      Specified by:
      size in interface Collection<S extends Shape>
      Specified by:
      size in interface List<S extends Shape>
      Specified by:
      size in class AbstractCollection<S extends Shape>
    • getBoundingBox

      public Rectangle getBoundingBox()
      Description copied from interface: Shape
      Get the bounding box for this Shape. This means the shape is within the bounding box and that it touches each side of the rectangle.

      Postcondition: this.getBoundingBox().relate(this) == CONTAINS

      Specified by:
      getBoundingBox in interface Shape
    • getCenter

      public Point getCenter()
      Description copied from interface: Shape
      Returns the center point of this shape. This is usually the same as getBoundingBox().getCenter() but it doesn't have to be.

      Postcondition: this.relate(this.getCenter()) == CONTAINS

      Specified by:
      getCenter in interface Shape
    • hasArea

      public boolean hasArea()
      Description copied from interface: Shape
      Does the shape have area? This will be false for points and lines. It will also be false for shapes that normally have area but are constructed in a degenerate case as to not have area (e.g. a circle with 0 radius or rectangle with no height or no width).
      Specified by:
      hasArea in interface Shape
    • getBuffered

      public ShapeCollection getBuffered(double distance, SpatialContext ctx)
      Description copied from interface: Shape
      Returns a buffered version of this shape. The buffer is usually a rounded-corner buffer, although some shapes might buffer differently. This is an optional operation.
      Specified by:
      getBuffered in interface Shape
      Returns:
      Not null, and the returned shape should contain the current shape.
    • relate

      public SpatialRelation relate(Shape other)
      Description copied from interface: Shape
      Describe the relationship between the two objects. For example
      • this is WITHIN other
      • this CONTAINS other
      • this is DISJOINT other
      • this INTERSECTS other
      Note that a Shape implementation may choose to return INTERSECTS when the true answer is WITHIN or CONTAINS for performance reasons. If a shape does this then it must document when it does. Ideally the shape will not do this approximation in all circumstances, just sometimes.

      If the shapes are equal then the result is CONTAINS (preferred) or WITHIN.

      Specified by:
      relate in interface Shape
    • relateContainsShortCircuits

      protected boolean relateContainsShortCircuits()
      Called by relate() to determine whether to return early if it finds CONTAINS, instead of checking the remaining shapes. It will do so without calling this method if the "other" shape is a Point. If a remaining shape finds INTERSECTS, then INTERSECTS will be returned. The only problem with this returning true is that if some of the shapes overlap, it's possible that the result of relate() could be dependent on the order of the shapes, which could be unexpected / wrong depending on the application. The default implementation returns true because it probably doesn't matter. If it does, a subclass could add a boolean flag that this method could return. That flag could be initialized to true only if the shapes are mutually disjoint.
      See Also:
    • computeMutualDisjoint

      protected static boolean computeMutualDisjoint(List<? extends Shape> shapes)
      Computes whether the shapes are mutually disjoint. This is a utility method offered for use by a subclass implementing relateContainsShortCircuits(). Beware: this is an O(N^2) algorithm.. Consequently, consider safely assuming non-disjoint if shapes.size() > 10 or something. And if all shapes are a Point then the result of this method doesn't ultimately matter.
    • getArea

      public double getArea(SpatialContext ctx)
      Description copied from interface: Shape
      Calculates the area of the shape, in square-degrees. If ctx is null then simple Euclidean calculations will be used. This figure can be an estimate.
      Specified by:
      getArea in interface Shape
    • toString

      public String toString()
      Overrides:
      toString in class AbstractCollection<S extends Shape>
    • equals

      public boolean equals(Object o)
      Description copied from interface: Shape
      The sub-classes of Shape generally implement the same contract for Object.equals(Object) and Object.hashCode() amongst the same sub-interface type. This means, for example, that multiple Point implementations of different classes are equal if they share the same x & y.
      Specified by:
      equals in interface Collection<S extends Shape>
      Specified by:
      equals in interface List<S extends Shape>
      Specified by:
      equals in interface Shape
      Overrides:
      equals in class AbstractList<S extends Shape>
    • hashCode

      public int hashCode()
      Specified by:
      hashCode in interface Collection<S extends Shape>
      Specified by:
      hashCode in interface List<S extends Shape>
      Overrides:
      hashCode in class AbstractList<S extends Shape>
    • getContext

      public SpatialContext getContext()
      Description copied from interface: Shape
      Get the SpatialContext that created the Shape
      Specified by:
      getContext in interface Shape