Class Envelopes

java.lang.Object
org.apache.sis.util.Static
org.apache.sis.geometry.Envelopes

public final class Envelopes extends Static
Transforms envelopes to new Coordinate Reference Systems, and miscellaneous utilities.

Envelope transformations

All transform(…) methods in this class take in account the curvature of the transformed shape. For example, the shape of a geographic envelope (figure below on the left side) is not rectangular in a conic projection (figure below on the right side). In order to get the envelope represented by the red rectangle, projecting the four corners of the geographic envelope is not sufficient since we would miss the southerner part.
Example of curvature induced by a map projection
Envelope before map projection Shape of the projected envelope
Envelope in a geographic CRS Shape of the envelope transformed in a conic projection
Apache SIS tries to detect the curvature by transforming intermediate points in addition to the corners. While optional, it is strongly recommended that all MathTransform implementations involved in the operation (directly or indirectly) support derivative, for more accurate calculation of curve extremum. This is the case of most Apache SIS implementations.

The transform(…) methods in this class expect an arbitrary Envelope with one of the following arguments: MathTransform, CoordinateOperation or CoordinateReferenceSystem. The recommended method is the one expecting a CoordinateOperation object, since it contains sufficient information for handling the cases of envelopes that encompass a pole. The method expecting a CoordinateReferenceSystem object is merely a convenience method that infers the coordinate operation itself, but at the cost of performance if the same operation needs to be applied on many envelopes.

Since:
0.3
Version:
1.3
See Also:
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private static final boolean[]
    Enumeration of the 4 corners in an envelope, with repetition of the first point.
    (package private) static final double
    Fraction of the axis span to accept as close enough to an envelope boundary.
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    Do not allow instantiation of this class.
  • Method Summary

    Modifier and Type
    Method
    Description
    static org.opengis.geometry.Envelope
    compound(org.opengis.geometry.Envelope... components)
    Puts together a list of envelopes, each of them using an independent coordinate reference system.
    (package private) static org.opengis.referencing.operation.Matrix
    derivativeAndTransform(org.opengis.referencing.operation.MathTransform transform, double[] srcPts, double[] dstPts, int dstOff, boolean derivate)
    A buckle method for calculating derivative and coordinate transformation in a single step, if the given derivative argument is true.
    static org.opengis.referencing.operation.CoordinateOperation
    findOperation(org.opengis.geometry.Envelope source, org.opengis.geometry.Envelope target)
    Finds a mathematical operation from the CRS of the given source envelope to the CRS of the given target envelope.
    static org.opengis.geometry.Envelope
    Returns the bounding box of a geometry defined in Well Known Text (WKT) format.
    intersect(org.opengis.geometry.Envelope... envelopes)
    Computes the intersection of all given envelopes, transforming them to a common CRS if necessary.
    (package private) static void
    recoverableException(Class<? extends Static> caller, org.opengis.referencing.operation.TransformException exception)
    Invoked when a recoverable exception occurred.
    static String
    toPolygonWKT(org.opengis.geometry.Envelope envelope)
    Formats the given envelope as a POLYGON element in the Well Known Text (WKT) format.
    static String
    toString(org.opengis.geometry.Envelope envelope)
    Formats the given envelope as a BOX element.
    toTimeRange(org.opengis.geometry.Envelope envelope)
    Returns the time range of the first dimension associated to a temporal CRS.
    static org.opengis.geometry.Envelope
    transform(org.opengis.geometry.Envelope envelope, org.opengis.referencing.crs.CoordinateReferenceSystem targetCRS)
    Transforms the given envelope to the specified CRS.
    transform(org.opengis.referencing.operation.CoordinateOperation operation, org.opengis.geometry.Envelope envelope)
    Transforms an envelope using the given coordinate operation.
    transform(org.opengis.referencing.operation.MathTransform transform, org.opengis.geometry.Envelope envelope)
    Transforms an envelope using the given math transform.
    private static GeneralEnvelope
    transform(org.opengis.referencing.operation.MathTransform transform, org.opengis.geometry.Envelope envelope, double[] targetPt, List<GeneralEnvelope> results)
    Shared implementation of transform(MathTransform, Envelope) and wraparound(MathTransform, Envelope) public methods.
    union(org.opengis.geometry.Envelope... envelopes)
    Computes the union of all given envelopes, transforming them to a common CRS if necessary.
    wraparound(org.opengis.referencing.operation.MathTransform transform, org.opengis.geometry.Envelope envelope)
    Transforms potentially many times an envelope using the given math transform.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • SPAN_FRACTION_AS_BOUND

      static final double SPAN_FRACTION_AS_BOUND
      Fraction of the axis span to accept as close enough to an envelope boundary. This is used for coordinates that are suppose to be on a boundary, for checking if it is really on the boundary side where it should be. For example, on the longitude axis, bounds are -180° and +180° with wraparound meaning and the span is 360°. A SPAN_FRACTION_AS_BOUND value of 0.25 means that we accept a margin of 0.25 × 360° = 90° on each side: longitudes between -180 and -90 are clipped to the -180° bounds, and longitudes between +180 and +90 and clipped to the +180° bounds. We use a large fraction because we use it in contexts where the longitude is not supposed to be in the envelope interior. We could use a 0.5 value for clipping to the nearest bound, but a smaller value is used for safety.
      See Also:
    • CORNERS

      private static final boolean[] CORNERS
      Enumeration of the 4 corners in an envelope, with repetition of the first point. The values are (x,y) pairs with false meaning "minimal value" and true meaning "maximal value". This is used by toPolygonWKT(Envelope) only.
  • Constructor Details

    • Envelopes

      private Envelopes()
      Do not allow instantiation of this class.
  • Method Details

    • compound

      public static org.opengis.geometry.Envelope compound(org.opengis.geometry.Envelope... components) throws org.opengis.util.FactoryException
      Puts together a list of envelopes, each of them using an independent coordinate reference system. The dimension of the returned envelope is the sum of the dimension of all components. If all components have a coordinate reference system, then the returned envelope will have a compound coordinate reference system.
      Parameters:
      components - the envelopes to aggregate in a single envelope, in the given order.
      Returns:
      the aggregation of all given envelopes.
      Throws:
      org.opengis.util.FactoryException - if the geodetic factory failed to create the compound CRS.
      Since:
      1.0
      See Also:
    • union

      public static GeneralEnvelope union(org.opengis.geometry.Envelope... envelopes) throws org.opengis.referencing.operation.TransformException
      Computes the union of all given envelopes, transforming them to a common CRS if necessary. If all envelopes use the same CRS (ignoring metadata) or if the CRS of all envelopes is null, then the union is computed without transforming any envelope. Otherwise all envelopes are transformed to a common CRS before union is computed. The CRS of the returned envelope may different than the CRS of all given envelopes.
      Parameters:
      envelopes - the envelopes for which to compute union. Null elements are ignored.
      Returns:
      union of given envelopes, or null if the given array does not contain non-null elements.
      Throws:
      org.opengis.referencing.operation.TransformException - if this method cannot determine a common CRS, or if a transformation failed.
      Since:
      1.0
      See Also:
    • intersect

      public static GeneralEnvelope intersect(org.opengis.geometry.Envelope... envelopes) throws org.opengis.referencing.operation.TransformException
      Computes the intersection of all given envelopes, transforming them to a common CRS if necessary. If all envelopes use the same CRS (ignoring metadata) or if the CRS of all envelopes is null, then the intersection is computed without transforming any envelope. Otherwise all envelopes are transformed to a common CRS before intersection is computed. The CRS of the returned envelope may different than the CRS of all given envelopes.
      Parameters:
      envelopes - the envelopes for which to compute intersection. Null elements are ignored.
      Returns:
      intersection of given envelopes, or null if the given array does not contain non-null elements.
      Throws:
      org.opengis.referencing.operation.TransformException - if this method cannot determine a common CRS, or if a transformation failed.
      Since:
      1.0
      See Also:
    • findOperation

      public static org.opengis.referencing.operation.CoordinateOperation findOperation(org.opengis.geometry.Envelope source, org.opengis.geometry.Envelope target) throws org.opengis.util.FactoryException
      Finds a mathematical operation from the CRS of the given source envelope to the CRS of the given target envelope. For non-null georeferenced envelopes, this method is equivalent to the following code with areaOfInterest computed as the union of the two envelopes:
      return CRS.findOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, GeographicBoundingBox) CRS.findOperation(source.getCoordinateReferenceSystem(), target.getCoordinateReferenceSystem(), areaOfInterest)
      If at least one envelope is null or has no CRS, then this method returns null.
      Parameters:
      source - the source envelope, or null.
      target - the target envelope, or null.
      Returns:
      the mathematical operation from source CRS to target CRS, or null if at least one argument is null or has no CRS.
      Throws:
      org.opengis.referencing.operation.OperationNotFoundException - if no operation was found between the given pair of CRS.
      org.opengis.util.FactoryException - if the operation cannot be created for another reason.
      Since:
      1.0
      See Also:
    • recoverableException

      static void recoverableException(Class<? extends Static> caller, org.opengis.referencing.operation.TransformException exception)
      Invoked when a recoverable exception occurred. Those exceptions must be minor enough that they can be silently ignored in most cases.
    • derivativeAndTransform

      static org.opengis.referencing.operation.Matrix derivativeAndTransform(org.opengis.referencing.operation.MathTransform transform, double[] srcPts, double[] dstPts, int dstOff, boolean derivate) throws org.opengis.referencing.operation.TransformException
      A buckle method for calculating derivative and coordinate transformation in a single step, if the given derivative argument is true.
      Parameters:
      transform - the transform to use.
      srcPts - the array containing the source coordinate at offset 0.
      dstPts - the array into which the transformed coordinate is returned.
      dstOff - the offset to the location of the transformed point that is stored in the destination array.
      derivate - true for computing the derivative, or false if not needed.
      Returns:
      the matrix of the transform derivative at the given source position, or null if the derivate argument is false.
      Throws:
      org.opengis.referencing.operation.TransformException - if the point cannot be transformed or if a problem occurred while calculating the derivative.
    • transform

      public static org.opengis.geometry.Envelope transform(org.opengis.geometry.Envelope envelope, org.opengis.referencing.crs.CoordinateReferenceSystem targetCRS) throws org.opengis.referencing.operation.TransformException
      Transforms the given envelope to the specified CRS. If any argument is null, or if the envelope CRS is null or the same instance than the given target CRS, then the given envelope is returned unchanged. Otherwise a new transformed envelope is returned.

      Performance tip

      If there is many envelopes to transform with the same source and target CRS, then it is more efficient to get the CoordinateOperation or MathTransform instance once and invoke one of the others transform(…) methods.
      Parameters:
      envelope - the envelope to transform (may be null).
      targetCRS - the target CRS (may be null).
      Returns:
      a new transformed envelope, or directly envelope if no change was required.
      Throws:
      org.opengis.referencing.operation.TransformException - if a transformation was required and failed.
      Since:
      0.5
    • transform

      private static GeneralEnvelope transform(org.opengis.referencing.operation.MathTransform transform, org.opengis.geometry.Envelope envelope, double[] targetPt, List<GeneralEnvelope> results) throws org.opengis.referencing.operation.TransformException
      Shared implementation of transform(MathTransform, Envelope) and wraparound(MathTransform, Envelope) public methods. Offers also the opportunity to save the transformed center coordinates.
      Parameters:
      transform - the transform to use.
      envelope - envelope to transform. This envelope will not be modified.
      targetPt - after this method call, the center of the source envelope transformed to the target CRS. The length of this array must be the number of target dimensions. May be null if this information is not needed.
      results - where to store the individual results when the transform contains wraparound steps, or null for computing the union of all results instead.
      Returns:
      the transformed envelope. May be null if results was non-null.
      Throws:
      org.opengis.referencing.operation.TransformException
    • transform

      public static GeneralEnvelope transform(org.opengis.referencing.operation.CoordinateOperation operation, org.opengis.geometry.Envelope envelope) throws org.opengis.referencing.operation.TransformException
      Transforms an envelope using the given coordinate operation. The transformation is only approximated: the returned envelope may be bigger than the smallest possible bounding box, but should not be smaller in most cases.

      This method can handle the case where the envelope contains the North or South pole, or when it cross the ±180° longitude.

      Note: If the envelope CRS is non-null, then the caller should ensure that the operation source CRS is the same than the envelope CRS. In case of mismatch, this method transforms the envelope to the operation source CRS before to apply the operation. This extra step may cause a lost of accuracy. In order to prevent this method from performing such pre-transformation (if not desired), callers can ensure that the envelope CRS is null before to call this method.
      Parameters:
      operation - the operation to use.
      envelope - envelope to transform, or null. This envelope will not be modified.
      Returns:
      the transformed envelope, or null if envelope was null.
      Throws:
      org.opengis.referencing.operation.TransformException - if a transform failed.
      Since:
      0.5
      See Also:
    • transform

      public static GeneralEnvelope transform(org.opengis.referencing.operation.MathTransform transform, org.opengis.geometry.Envelope envelope) throws org.opengis.referencing.operation.TransformException
      Transforms an envelope using the given math transform. The transformation is only approximated: the returned envelope may be bigger than necessary, or smaller than required if the bounding box contains a pole. The coordinate reference system of the returned envelope will be null.

      Limitation

      This method cannot handle the case where the envelope contains the North or South pole. Envelopes crossing the ±180° longitude are handled only if the given transform contains WraparoundTransform steps; this method does not add such steps itself. For a more robust envelope transformation, use transform(CoordinateOperation, Envelope) instead.
      Parameters:
      transform - the transform to use.
      envelope - envelope to transform, or null. This envelope will not be modified.
      Returns:
      the transformed envelope, or null if envelope was null.
      Throws:
      org.opengis.referencing.operation.TransformException - if a transform failed.
      Since:
      0.5
      See Also:
    • wraparound

      public static GeneralEnvelope[] wraparound(org.opengis.referencing.operation.MathTransform transform, org.opengis.geometry.Envelope envelope) throws org.opengis.referencing.operation.TransformException
      Transforms potentially many times an envelope using the given math transform. If the given envelope is null, then this method returns an empty envelope. Otherwise if the transform does not contain any WraparoundTransform step, then this method is equivalent to transform(MathTransform, Envelope) returned in an array of length 1. Otherwise this method returns many transformed envelopes where each envelope describes approximately the same region. If the envelope CRS is geographic, the many envelopes are the same envelope shifted by 360° of longitude. If the envelope CRS is projected, then the 360° shifts are applied before the map projection. It may result in very different coordinates.
      Parameters:
      transform - the transform to use.
      envelope - envelope to transform, or null. This envelope will not be modified.
      Returns:
      the transformed envelopes, or an empty array if envelope was null.
      Throws:
      org.opengis.referencing.operation.TransformException - if a transform failed.
      Since:
      1.3
      See Also:
    • fromWKT

      public static org.opengis.geometry.Envelope fromWKT(CharSequence wkt) throws org.opengis.util.FactoryException
      Returns the bounding box of a geometry defined in Well Known Text (WKT) format. This method does not check the consistency of the provided WKT. For example, it does not check that every points in a LINESTRING have the same dimension. However, this method ensures that the parenthesis are balanced, in order to catch some malformed WKT.
      Examples:
      • BOX(-180 -90, 180 90) (not really a geometry, but understood by many software products)
      • POINT(6 10)
      • MULTIPOLYGON(((1 1, 5 1, 1 5, 1 1),(2 2, 3 2, 3 3, 2 2)))
      • GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(3 8,7 10))
      See GeneralEnvelope(CharSequence) for more information about the parsing rules.
      Parameters:
      wkt - the BOX, POLYGON or other kind of element to parse.
      Returns:
      the envelope of the given geometry.
      Throws:
      org.opengis.util.FactoryException - if the given WKT cannot be parsed.
      See Also:
    • toString

      public static String toString(org.opengis.geometry.Envelope envelope)
      Formats the given envelope as a BOX element. The output is like below, where n is the number of dimensions (omitted if equals to 2):
      BOXnD(lower corner, upper corner)
      Note: The BOX element is not part of the standard Well Known Text (WKT) format. However, it is understood by many software libraries, for example GDAL and PostGIS.
      The string returned by this method can be parsed by the GeneralEnvelope constructor.
      Parameters:
      envelope - the envelope to format.
      Returns:
      this envelope as a BOX or BOX3D (most typical dimensions) element.
      See Also:
    • toPolygonWKT

      public static String toPolygonWKT(org.opengis.geometry.Envelope envelope) throws IllegalArgumentException
      Formats the given envelope as a POLYGON element in the Well Known Text (WKT) format. POLYGON can be used as an alternative to BOX when the element needs to be considered as a standard WKT geometry.

      The string returned by this method can be parsed by the GeneralEnvelope constructor.

      Parameters:
      envelope - the envelope to format.
      Returns:
      the envelope as a POLYGON in WKT format.
      Throws:
      IllegalArgumentException - if the given envelope cannot be formatted.
      See Also:
    • toTimeRange

      public static Optional<Range<Instant>> toTimeRange(org.opengis.geometry.Envelope envelope)
      Returns the time range of the first dimension associated to a temporal CRS. This convenience method converts floating point values to instants using DefaultTemporalCRS.toInstant(double).
      Parameters:
      envelope - envelope from which to extract time range, or null if none.
      Returns:
      time range in the given envelope.
      Since:
      1.1
      See Also: