Class GeometryWrapper<G>

java.lang.Object
org.apache.sis.internal.feature.AbstractGeometry
org.apache.sis.internal.feature.GeometryWrapper<G>
Type Parameters:
G - root class of geometry instances of the underlying library (i.e. Geometries.rootClass). This is not necessarily the class of the wrapped geometry returned by implementation().
All Implemented Interfaces:
org.opengis.geometry.Geometry
Direct Known Subclasses:
GeometryWithCRS, Wrapper

public abstract class GeometryWrapper<G> extends AbstractGeometry implements org.opengis.geometry.Geometry
Wraps a JTS, ESRI or Java2D geometry behind a Geometry interface. This is a temporary class to be refactored later as a more complete geometry framework. The methods provided in this class are not committed API, and often not even clean API. They are only utilities added for very specific Apache SIS needs and will certainly change without warning in future Apache SIS version.
Since:
0.8
Version:
1.1
See Also:
  • Constructor Details

    • GeometryWrapper

      protected GeometryWrapper()
      Creates a new geometry object.
  • Method Details

    • factory

      public abstract Geometries<G> factory()
      Returns the implementation-dependent factory of geometric objects. This is typically a system-wide factory shared by all geometry instances.
      Returns:
      the factory of implementation-dependent geometric objects (never null).
    • implementation

      public abstract Object implementation()
      Returns the JTS, ESRI or Java2D geometry implementation wrapped by this GeometryWrapper instance. This returned object will be an instance of Geometries.rootClass or Geometries.pointClass (note that pointClass is not necessarily a subtype of rootClass).
      Returns:
      the geometry implementation wrapped by this instance (never null).
    • getSRID

      public OptionalInt getSRID()
      Returns the Spatial Reference System Identifier (SRID) if available. The SRID is used in database such as PostGIS and is generally database-dependent. This is not necessarily an EPSG code, even it is common practice to use the same numerical values than EPSG. Note that the absence of SRID does not mean that getCoordinateReferenceSystem() would return no CRS.

      Users should invoke the getCoordinateReferenceSystem() method instead. This getSRID() method is provided for classes such as DataStore backed by an SQL database. Those classes have a connection to a "spatial_ref_sys table providing the mapping from SRID codes to authority codes such as EPSG. Those DataStore will typically get the SRID soon after geometry creation, resolves its CRS and invoke setCoordinateReferenceSystem(CoordinateReferenceSystem).

      Returns:
      the Spatial Reference System Identifier of the geometry.
    • getCoordinateReferenceSystem

      public abstract org.opengis.referencing.crs.CoordinateReferenceSystem getCoordinateReferenceSystem()
      Gets the Coordinate Reference System (CRS) of this geometry. In some libraries (for example JTS) the CRS is stored in the Geometries.rootClass instances of that library. In other libraries (e.g. Java2D) the CRS is stored only in this GeometryWrapper instance.
      Returns:
      the geometry CRS, or null if unknown.
      Throws:
      BackingStoreException - if the CRS is defined by a SRID code and that code cannot be used.
    • setCoordinateReferenceSystem

      public abstract void setCoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem crs)
      Sets the coordinate reference system. This method should be invoked only for newly created geometries. If the geometry library supports user objects (e.g. JTS), there is no guarantee that this method will not overwrite user setting.
      Parameters:
      crs - the coordinate reference system to set.
      See Also:
    • getEnvelope

      public abstract GeneralEnvelope getEnvelope()
      Returns the geometry bounding box, together with its coordinate reference system.
      Returns:
      the geometry envelope. Should never be null. Note though that for an empty geometry or a single point, the returned envelope will be empty.
    • getCentroid

      public abstract org.opengis.geometry.DirectPosition getCentroid()
      Returns the mathematical centroid (if possible) or center (as a fallback) as a direct position.
      Returns:
      the centroid of the wrapped geometry.
    • getPointCoordinates

      public abstract double[] getPointCoordinates()
      If the geometry implementation is a point, returns its coordinates. Otherwise returns null. If non-null, the returned array may have a length of 2 or 3. If the CRS is geographic, then the (x,y) values should be in (longitude, latitude) order for compliance with usage in ESRI and JTS libraries.
      Returns:
      the coordinate of the point as an array of length 2 or 3, or null if the geometry is not a point.
      See Also:
    • getAllCoordinates

      @Debug public abstract double[] getAllCoordinates()
      Returns all geometry coordinate tuples. This method is currently used for testing purpose only because it does not separate the sequence of coordinates for different polygons in a multi-polygon.
      Returns:
      the sequence of all coordinate values in the wrapped geometry, or null if they cannot be obtained.
    • mergePolylines

      protected abstract G mergePolylines(Iterator<?> paths)
      Appends a sequence of points or polylines after this geometry. Each previous polyline will be a separated path in the new polyline instance.

      The given iterator shall return instances of Geometries.rootClass or Geometries.pointClass, not not GeometryWrapper (it is caller responsibility to unwrap if needed).

      Parameters:
      paths - the points or polylines to merge in a single polyline instance.
      Returns:
      the merged polyline (may be the wrapper geometry but never null).
      Throws:
      ClassCastException - if collection elements are not instances of the point or geometry class.
    • predicate

      public final boolean predicate(DistanceOperatorName type, GeometryWrapper<G> other, javax.measure.Quantity<javax.measure.quantity.Length> distance, SpatialOperationContext context)
      Applies a filter predicate between this geometry and another geometry. This method transforms the two geometries to the same CRS if needed.
      Parameters:
      type - the predicate operation to apply.
      other - the other geometry to test with this geometry.
      distance - the buffer distance around the geometry of the second expression.
      context - the preferred CRS and other context to use if geometry transformations are needed.
      Returns:
      result of applying the specified predicate.
      Throws:
      UnsupportedOperationException - if the operation cannot be performed with current implementation.
      IllegalArgumentException - if an error occurred while executing the operation on given geometries.
    • predicate

      public final boolean predicate(SpatialOperatorName type, GeometryWrapper<G> other, SpatialOperationContext context)
      Applies a filter predicate between this geometry and another geometry. This method transforms the two geometries to the same CRS if needed.

      Note: SpatialOperatorName.BBOX is implemented by NOT DISJOINT. It is caller's responsibility to ensure that one of the geometries is rectangular.

      Parameters:
      type - the predicate operation to apply.
      other - the other geometry to test with this geometry.
      context - the preferred CRS and other context to use if geometry transformations are needed.
      Returns:
      result of applying the specified predicate.
      Throws:
      UnsupportedOperationException - if the operation cannot be performed with current implementation.
      IllegalArgumentException - if an error occurred while executing the operation on given geometries.
    • operation

      public final Object operation(SQLMM operation)
      Applies a SQLMM operation on this geometry. This method shall be invoked only for operations without non-geometric parameters.
      Parameters:
      operation - the SQLMM operation to apply.
      Returns:
      result of the specified operation.
      Throws:
      UnsupportedOperationException - if the operation cannot be performed with current implementation.
      ClassCastException - if the operation can only be executed on some specific geometry subclasses (for example polylines) and the wrapped geometry is not of that class.
    • operation

      public final Object operation(SQLMM operation, GeometryWrapper<G> other) throws org.opengis.referencing.operation.TransformException
      Applies a SQLMM operation on two geometries. This method shall be invoked only for operations without non-geometric parameters. The second geometry is transformed to the same CRS than this geometry for conformance with SQLMM standard.
      Parameters:
      operation - the SQLMM operation to apply.
      other - the other geometry. It is caller's responsibility to check that this value is non-null.
      Returns:
      result of the specified operation.
      Throws:
      UnsupportedOperationException - if the operation cannot be performed with current implementation.
      ClassCastException - if the operation can only be executed on some specific geometry subclasses (for example polylines) and the wrapped geometry is not of that class.
      org.opengis.referencing.operation.TransformException - if it was necessary to transform the other geometry and that transformation failed.
    • operationWithArgument

      public final Object operationWithArgument(SQLMM operation, Object argument)
      Applies a SQLMM operation on this geometry with one operation-specific argument. The argument shall be non-null, unless the argument is optional.
      Parameters:
      operation - the SQLMM operation to apply.
      argument - an operation-specific argument.
      Returns:
      result of the specified operation.
      Throws:
      UnsupportedOperationException - if the operation cannot be performed with current implementation.
      ClassCastException - if the operation can only be executed on some specific geometry subclasses (for example polylines) and the wrapped geometry is not of that class.
    • operationWithArgument

      public final Object operationWithArgument(SQLMM operation, GeometryWrapper<G> other, Object argument) throws org.opengis.referencing.operation.TransformException
      Applies a SQLMM operation on two geometries with one operation-specific argument. The argument shall be non-null, unless the argument is optional. The second geometry is transformed to the same CRS than this geometry for conformance with SQLMM standard.
      Parameters:
      operation - the SQLMM operation to apply.
      other - the other geometry. It is caller's responsibility to check that this value is non-null.
      argument - an operation-specific argument.
      Returns:
      result of the specified operation.
      Throws:
      UnsupportedOperationException - if the operation cannot be performed with current implementation.
      ClassCastException - if the operation can only be executed on some specific geometry subclasses (for example polylines) and the wrapped geometry is not of that class.
      org.opengis.referencing.operation.TransformException - if it was necessary to transform the other geometry and that transformation failed.
    • toSameCRS

      private GeometryWrapper<G> toSameCRS(GeometryWrapper<G> other) throws org.opengis.referencing.operation.TransformException
      Transforms the other geometry to the same CRS than this geometry. This method should be cheap for the common case where the other geometry already uses the CRS, in which case it is returned unchanged.

      If this geometry does not define a CRS, then current implementation returns the other geometry unchanged.

      Parameters:
      other - the other geometry.
      Returns:
      the other geometry in the same CRS than this geometry.
      Throws:
      org.opengis.referencing.operation.TransformException - if the other geometry cannot be transformed. If may be because the other geometry does not define its CRS.
    • isInstance

      private boolean isInstance(SQLMM operation, Object result)
      Returns true if a result is of the expected type. This is used for assertion purposes only.
    • predicateSameCRS

      protected boolean predicateSameCRS(SpatialOperatorName type, GeometryWrapper<G> other)
      Applies a filter predicate between this geometry and another geometry. This method assumes that the two geometries are in the same CRS (this is not verified).

      Note: SpatialOperatorName.BBOX is implemented by NOT DISJOINT. It is caller's responsibility to ensure that one of the geometries is rectangular.

      Parameters:
      type - the predicate operation to apply.
      other - the other geometry to test with this geometry.
      Returns:
      result of applying the specified predicate.
      Throws:
      UnsupportedOperationException - if the operation cannot be performed with current implementation.
    • predicateSameCRS

      protected boolean predicateSameCRS(DistanceOperatorName type, GeometryWrapper<G> other, double distance)
      Applies a filter predicate between this geometry and another geometry within a given distance. This method assumes that the two geometries are in the same CRS and that the unit of measurement is the same for distance than for axes (this is not verified).
      Parameters:
      type - the predicate operation to apply.
      other - the other geometry to test with this geometry.
      distance - distance to test between the geometries.
      Returns:
      result of applying the specified predicate.
      Throws:
      UnsupportedOperationException - if the operation cannot be performed with current implementation.
    • operationSameCRS

      protected Object operationSameCRS(SQLMM operation, GeometryWrapper<G> other, Object argument)
      Applies a SQLMM operation on this geometry.
      Parameters:
      operation - the SQLMM operation to apply.
      other - the other geometry, or null if the operation requires only one geometry.
      argument - an operation-specific argument, or null if not applicable.
      Returns:
      result of the specified operation.
      Throws:
      UnsupportedOperationException - if the operation cannot be performed with current implementation.
      ClassCastException - if the operation can only be executed on some specific geometry subclasses (for example polylines) and the wrapped geometry is not of that class.
    • toGeometryType

      public GeometryWrapper<G> toGeometryType(GeometryType target)
      Converts the given geometry to the specified type. If the geometry is already of that type, it is returned unchanged. Otherwise coordinates are copied in a new geometry of the requested type.

      The following conversions are illegal and will cause an IllegalArgumentException to be thrown:

      • From point to polyline or polygon.
      • From geometry collection (except multi-point) to polyline.
      • From geometry collection (except multi-point and multi-line string) to polygon.
      • From geometry collection containing nested collections.
      The conversion from MultiLineString to Polygon is defined as following: the first LineString is taken as the exterior LinearRing and all others LineStrings are interior LinearRings. This rule is defined by some SQLMM operations.
      Parameters:
      target - the desired type.
      Returns:
      the converted geometry.
      Throws:
      IllegalArgumentException - if the geometry cannot be converted to the specified type.
    • transform

      public GeometryWrapper<G> transform(org.opengis.referencing.operation.CoordinateOperation operation, boolean validate) throws org.opengis.util.FactoryException, org.opengis.referencing.operation.TransformException
      Transforms this geometry using the given coordinate operation. If the operation is null, then the geometry is returned unchanged. If the geometry uses a different CRS than the source CRS of the given operation and validate is true, then a new operation to the target CRS will be automatically computed.

      This method is preferred to transform(CoordinateReferenceSystem) when possible because not all geometry libraries store the CRS of their objects.

      Parameters:
      operation - the coordinate operation to apply, or null.
      validate - whether to validate the operation source CRS.
      Returns:
      the transformed geometry (may be the same geometry instance, but never null).
      Throws:
      UnsupportedOperationException - if this operation is not supported for current implementation.
      org.opengis.util.FactoryException - if transformation to the target CRS cannot be found.
      org.opengis.referencing.operation.TransformException - if the geometry cannot be transformed.
    • transform

      public GeometryWrapper<G> transform(org.opengis.referencing.crs.CoordinateReferenceSystem targetCRS) throws org.opengis.referencing.operation.TransformException
      Transforms this geometry to the specified Coordinate Reference System (CRS). If the given CRS is null, then the geometry is returned unchanged. If this geometry has no Coordinate Reference System, a TransformException is thrown.

      Consider using #transform(CoordinateOperation) instead of this method as much as possible, both for performance reasons and because not all geometry libraries provide information about the CRS of their geometries.

      Parameters:
      targetCRS - the target coordinate reference system, or null.
      Returns:
      the transformed geometry (may be the same geometry but never null).
      Throws:
      UnsupportedOperationException - if this operation is not supported for current implementation.
      org.opengis.referencing.operation.TransformException - if the given geometry has no CRS or cannot be transformed.
      See Also:
    • isSameCRS

      public abstract boolean isSameCRS(GeometryWrapper<G> other)
      Returns true if the given geometry use the same CRS than this geometry, or conservatively returns false in case of doubt. This method should perform only a cheap test; it is used as a way to filter rapidly if transform(CoordinateReferenceSystem) needs to be invoked. If this method wrongly returned false, the transform(…) method will return the geometry unchanged anyway.

      If both CRS are undefined (null), then they are considered the same.

      Parameters:
      other - the second geometry.
      Returns:
      true if the two geometries use equivalent CRS or if the CRS is undefined on both side, or false in case of doubt.
    • formatWKT

      public abstract String formatWKT(double flatness)
      Formats the wrapped geometry in Well Known Text (WKT). If the geometry contains curves, then the flatness parameter specifies the maximum distance that the line segments used in the Well Known Text are allowed to deviate from any point on the original curve. This parameter is ignored if the geometry does not contain curves.
      Parameters:
      flatness - maximal distance between the approximated WKT and any point on the curve.
      Returns:
      the Well Known Text for the wrapped geometry (never null).
      See Also:
    • equals

      public final boolean equals(Object obj)
      Returns true if the given object is a wrapper of the same class and the wrapped geometry implementations are equal.
      Overrides:
      equals in class Object
      Parameters:
      obj - the object to compare with this wrapper.
      Returns:
      whether the two objects are wrapping geometry implementations that are themselves equal.
    • hashCode

      public final int hashCode()
      Returns a hash code value based on the wrapped geometry.
      Overrides:
      hashCode in class Object
    • toString

      public final String toString()
      Returns the string representation of the wrapped geometry (typically the class name and the bounds).
      Overrides:
      toString in class Object