Class Geometries<G>

java.lang.Object
org.apache.sis.internal.feature.Geometries<G>
Type Parameters:
G - the base class of all geometry objects (except point in some implementations).
All Implemented Interfaces:
Serializable
Direct Known Subclasses:
Factory, Factory, Factory

public abstract class Geometries<G> extends Object implements Serializable
Utility methods on geometric objects defined in libraries outside Apache SIS. We use this class for isolating dependencies from the org.apache.feature package to ESRI's API or to Java Topology Suite (JTS) API. This gives us a single place to review if we want to support different geometry libraries, or if Apache SIS come with its own implementation.

Serialization

All fields except library should be declared transient. Deserialized Geometries instances shall be replaced by a unique instance, which is given by
invalid reference
#readResolve()
.
Since:
0.7
Version:
1.3
See Also:
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      For cross-version compatibility.
      See Also:
    • BIDIMENSIONAL

      public static final int BIDIMENSIONAL
      The 2 value, used by subclasses for identifying code that assume two- or three-dimensional objects.
      See Also:
    • TRIDIMENSIONAL

      public static final int TRIDIMENSIONAL
      The 3 value, used by subclasses for identifying code that assume two- or three-dimensional objects.
      See Also:
    • library

      public final GeometryLibrary library
      The enumeration value that identifies which geometry library is used.
    • rootClass

      public final transient Class<G> rootClass
      The root geometry class.
    • pointClass

      public final transient Class<?> pointClass
      The class for points. This is often a subclass of rootClass but not necessarily.
    • polylineClass

      public final transient Class<? extends G> polylineClass
      The class for polylines and polygons.
    • polygonClass

      public final transient Class<? extends G> polygonClass
      The class for polylines and polygons.
    • fallback

      transient Geometries<?> fallback
      The fallback implementation to use if the default one is not available. This is set by GeometryFactories and should not change after initialization. We do not synchronize accesses to this field because we keep it stable after GeometryFactories class initialization.
    • isPointClassDistinct

      private final transient boolean isPointClassDistinct
      true if pointClass is not a subtype of rootClass. This is true for Java2D and false for JTS and ESRI libraries.
  • Constructor Details

    • Geometries

      protected Geometries(GeometryLibrary library, Class<G> rootClass, Class<?> pointClass, Class<? extends G> polylineClass, Class<? extends G> polygonClass)
      Creates a new adapter for the given root geometry class.
      Parameters:
      library - the enumeration value that identifies which geometry library is used.
      rootClass - the root geometry class.
      pointClass - the class for points.
      polylineClass - the class for polylines.
      polygonClass - the class for polygons.
  • Method Details

    • implementation

      public static Geometries<?> implementation(GeometryLibrary library)
      Returns a factory backed by the specified geometry library implementation, of the default implementation if the specified library is null.
      Parameters:
      library - the desired library, or null for the default.
      Returns:
      the specified or the default geometry implementation (never null).
      Throws:
      IllegalArgumentException - if a non-null library is specified by that library is not available.
    • implementation

      public static Geometries<?> implementation(Class<?> type)
      Returns a factory backed by the same implementation than the given type. If the given type is not recognized, then this method returns null.
      Parameters:
      type - the type for which to get a geometry factory.
      Returns:
      a geometry factory compatible with the given type if possible, or null otherwise.
    • isKnownType

      public static boolean isKnownType(Class<?> type)
      Returns true if the given type is one of the geometry types known to Apache SIS.
      Parameters:
      type - the type to verify.
      Returns:
      true if the given type is one of the geometry types known to SIS.
    • isSupportedType

      private boolean isSupportedType(Class<?> type)
      Returns true if the given class is a geometry type supported by the underlying library.
    • getGeometryClass

      public Class<?> getGeometryClass(GeometryType type)
      Returns the geometry class of the given instance.
      Parameters:
      type - type of geometry for which the class is desired.
      Returns:
      implementation class for the geometry of the specified type.
    • wrap

      public static Optional<GeometryWrapper<?>> wrap(Object geometry)
      Wraps the given geometry implementation if recognized. If the given object is already an instance of GeometryWrapper, then it is returned as-is. If the given object is not recognized, then this method returns an empty value.
      Parameters:
      geometry - the geometry instance to wrap (can be null).
      Returns:
      a wrapper for the given geometry implementation, or empty value.
      See Also:
    • castOrWrap

      public abstract GeometryWrapper<G> castOrWrap(Object geometry)
      Returns a wrapper for the given <G> or GeometryWrapper<G> instance. The given object can be one of the following choices:
      • null, in which case this method returns null.
      • An instance of GeometryWrapper<G>, in which case the given object is returned unchanged. Note that instances of GeometryWrapper<?> for implementations other than <G> will cause a ClassCastException to be thrown.
      • An instance of rootClass or pointClass.
      This method can be used as an alternative to wrap(Object) when the specified geometry shall be an implementation of the specific library.
      Parameters:
      geometry - the geometry instance to wrap (can be null).
      Returns:
      a wrapper for the given geometry implementation, or null if the given object was null.
      Throws:
      ClassCastException - if the the given object is not a wrapper or a geometry object of the implementation of the library identified by library.
      See Also:
    • unwrap

      protected static Object unwrap(Object geometry)
      If the given object is an instance of GeometryWrapper, returns the wrapped geometry implementation. Otherwise returns the given geometry unchanged.
      Parameters:
      geometry - the geometry to unwrap (can be null).
      Returns:
      the geometry implementation, or the given geometry as-is.
    • parseWKT

      public abstract GeometryWrapper<G> parseWKT(String wkt) throws Exception
      Parses the given Well Known Text (WKT).
      Parameters:
      wkt - the WKT to parse. Cannot be null.
      Returns:
      the geometry object for the given WKT (never null).
      Throws:
      Exception - if the WKT cannot be parsed. The exception sub-class depends on the implementation.
      See Also:
    • parseWKB

      public abstract GeometryWrapper<G> parseWKB(ByteBuffer data) throws Exception
      Reads the given bytes as a Well Known Binary (WKB) encoded geometry. Whether this method changes the buffer position or not is implementation-dependent.
      Parameters:
      data - the binary data in WKB format. Cannot be null.
      Returns:
      decoded geometry (never null).
      Throws:
      Exception - if the WKB cannot be parsed. The exception sub-class depends on the implementation.
    • createPoint

      public final GeometryWrapper<G> createPoint(org.opengis.geometry.DirectPosition point)
      Creates and wraps a point from the given position.
      Parameters:
      point - the point to convert to a geometry.
      Returns:
      the given point converted to a geometry.
    • supportSinglePrecision

      public boolean supportSinglePrecision()
      Returns whether this library can produce geometry backed by the float primitive type instead of the double primitive type. If single-precision mode is supported, using that mode may reduce memory usage. This method is used for checking whether it is worth to invoke Vector.isSinglePrecision() for example.
      Returns:
      whether the library support single-precision values.
      See Also:
    • createPoint

      public Object createPoint(float x, float y)
      Single-precision variant of createPoint(double, double). Default implementation delegates to the double-precision variant.
      Parameters:
      x - the first coordinate value.
      y - the second coordinate value.
      Returns:
      the point for the given coordinate values.
      See Also:
    • createPoint

      public abstract Object createPoint(double x, double y)
      Creates a two-dimensional point from the given coordinates. If the CRS is geographic, then the (x,y) values should be (longitude, latitude) for compliance with usage in ESRI and JTS libraries. The returned object will be an instance of pointClass.
      Parameters:
      x - the first coordinate value.
      y - the second coordinate value.
      Returns:
      the point for the given coordinate values.
      See Also:
    • createPoint

      public abstract Object createPoint(double x, double y, double z)
      Creates a three-dimensional point from the given coordinates. If the CRS is geographic, then the (x,y) values should be (longitude, latitude) for compliance with usage in ESRI and JTS libraries. The returned object will be an instance of pointClass.
      Parameters:
      x - the first coordinate value.
      y - the second coordinate value.
      z - the third coordinate value.
      Returns:
      the point for the given coordinate values.
      See Also:
    • createPolyline

      public abstract G createPolyline(boolean polygon, int dimension, Vector... coordinates)
      Creates a path, polyline or polygon from the given coordinate values. The array of coordinate values will be handled as if all vectors were concatenated in a single vector, ignoring null array elements. Each Double.NaN coordinate value in the concatenated vector starts a new path. The implementation returned by this method is an instance of rootClass.

      If the polygon argument is true, then the coordinates should make a closed line (e.g: a linear ring), otherwise an exception is thrown.

      Parameters:
      polygon - whether to return the path as a polygon instead of polyline.
      dimension - the number of dimensions (2<G> or 3<G>).
      coordinates - sequence of (x,y) or (x,y,z) tuples.
      Returns:
      the geometric object for the given points.
      Throws:
      UnsupportedOperationException - if the geometry library cannot create the requested path.
      IllegalArgumentException - if a polygon was requested but the given coordinates do not make a closed shape (linear ring).
    • createMultiPolygon

      public abstract GeometryWrapper<G> createMultiPolygon(Object[] geometries)
      Creates a multi-polygon from an array of geometries (polygons or linear rings). Callers must ensure that the given objects are instances of geometric classes of the underlying library. If some geometries are actually linear rings, current behavior is not well defined. Some implementations may convert polylines to polygons but this is not guaranteed.
      Parameters:
      geometries - the polygons or linear rings to put in a multi-polygons.
      Returns:
      the multi-polygon.
      Throws:
      ClassCastException - if an element in the array is not an implementation of backing library.
    • createFromComponents

      public abstract GeometryWrapper<G> createFromComponents(GeometryType type, Object components)
      Creates a geometry from components. The expected components type depend on the target geometry type:
      • If type is a multi-geometry, then the components should be implementation-specific Point[], Geometry[], LineString[] or Polygon[], depending on the desired target type.
      • Otherwise the components should be an array or collection of Point or Coordinate instances, or some implementation-specific object such as CoordinateSequence.
      Parameters:
      type - type of geometry to create.
      components - the components. Valid classes depend on the type of geometry to create.
      Returns:
      geometry built from the given components.
      Throws:
      ClassCastException - if the given object is not an array or a collection of supported geometry components.
    • createGeometry2D

      private GeometryWrapper<G> createGeometry2D(org.opengis.geometry.Envelope envelope, int xd, int yd, boolean expand, boolean addPts)
      Creates a polyline made of points describing a rectangle whose start point is the lower left corner. The sequence of points describes each corner, going in clockwise direction and repeating the starting point to properly close the ring. If wraparound may happen on at least one axis, then this method may add intermediate points on the axes where the envelope crosses the axis limit.
      Parameters:
      xd - dimension of first axis.
      yd - dimension of second axis.
      expand - whether to expand the envelope to full axis range if there is a wraparound.
      addPts - whether to allow insertion of intermediate points on edges of axis domains.
      Returns:
      a polyline made of a sequence of at least 5 points describing the given rectangle.
    • toGeometry2D

      public GeometryWrapper<G> toGeometry2D(org.opengis.geometry.Envelope envelope, WraparoundMethod strategy)
      Transforms an envelope to a two-dimensional polygon whose start point is lower corner and other points are the envelope corners in clockwise order. The specified envelope should be two-dimensional (see for example GeneralEnvelope.horizontal()) but the coordinates does not need to be in (longitude, latitude) order; this method will preserve envelope horizontal axis order. It means that any non-2D axis will be ignored, and the first horizontal axis in the envelope will be the first axis (x) in the resulting geometry. To force AxesConvention.RIGHT_HANDED, should transform the bounding box before calling this method.
      Parameters:
      envelope - the envelope to convert.
      strategy - how to resolve wrap-around ambiguities on the envelope.
      Returns:
      the envelope as a polygon, or potentially as two polygons in WraparoundMethod.SPLIT case.
    • mergePolylines

      public static Object mergePolylines(Iterator<?> paths)
      Merges a sequence of points or polylines into a single polyline instances. Each previous polyline will be a separated path in the new polyline instances. The implementation returned by this method is an instance of rootClass.

      Contrarily to other methods in this class, this method does not unwrap the geometries contained in GeometryWrapper. It is caller responsibility to do so if needed.

      Parameters:
      paths - the points or polylines to merge in a single polyline object.
      Returns:
      the merged polyline, or null if the given iterator has no element.
      Throws:
      ClassCastException - if collection elements are not instances of a supported library, or not all elements are instances of the same library.
    • createWrapper

      protected abstract GeometryWrapper<G> createWrapper(G geometry)
      Creates a wrapper for the given geometry instance. The given object shall be an instance of rootClass.
      Parameters:
      geometry - the geometry to wrap.
      Returns:
      wrapper for the given geometry.
      Throws:
      ClassCastException - if the given geometry is not an instance of valid type.
      See Also:
    • unsupported

      protected static String unsupported(String operation)
      Returns an error message for an unsupported operation. This error message is used by non-abstract methods in Geometries subclasses, after we identified the geometry library implementation to use but that library does not provided the required functionality.
      Parameters:
      operation - name of the unsupported operation.
      Returns:
      error message to put in the exception to be thrown.
    • unsupported

      protected static String unsupported(int dimension)
      Returns an error message for an unsupported number of dimensions in a geometry object.
      Parameters:
      dimension - number of dimensions (2 or 3) requested for the geometry object.
      Returns:
      error message to put in the exception to be thrown.