Package org.apache.sis.geometry

## Class ImmutableEnvelope

- Object
- - FormattableObject
  - - AbstractEnvelope
    - - ImmutableEnvelope

- All Implemented Interfaces:
    `Serializable`, `Emptiable`, `Envelope`

      public final class ImmutableEnvelope
      extends AbstractEnvelope
      implements Serializable

  An immutable `Envelope` (a minimum bounding box or rectangle) of arbitrary dimension. This class is final in order to ensure that the immutability contract can not be broken (assuming not using Java Native Interface or reflections).
  Immutability and thread safety
  This final class is immutable and thus inherently thread-safe if the `CoordinateReferenceSystem` instance given to the constructor is immutable. This is usually the case in Apache SIS.
  Since:
    0.3
  See Also:
    Serialized Form

  Defined in the `sis-referencing` module

- - ### Constructor Summary

    Constructors
    Constructor | Description
    --- | ---
    `ImmutableEnvelope​(double[] lowerCorner, double[] upperCorner, CoordinateReferenceSystem crs)` | Constructs an envelope defined by two corners given as sequences of coordinate values.
    `ImmutableEnvelope​(DirectPosition lowerCorner, DirectPosition upperCorner)` | Constructs an envelope defined by two corners given as direct positions.
    `ImmutableEnvelope​(Envelope envelope)` | Creates an immutable envelope with the values of the given envelope.
    `ImmutableEnvelope​(GeographicBoundingBox box)` | Constructs a new envelope with the same data than the specified geographic bounding box.
    `ImmutableEnvelope​(CoordinateReferenceSystem crs, CharSequence wkt)` | Constructs a new envelope initialized to the values parsed from the given string in `BOX` or Well Known Text (WKT) format.
    `ImmutableEnvelope​(CoordinateReferenceSystem crs, Envelope envelope)` | Creates an immutable envelope with the coordinate values of the given envelope but a different CRS.

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `static ImmutableEnvelope` | `castOrCopy​(Envelope envelope)` | Returns the given envelope as an `ImmutableEnvelope` instance.
    `boolean` | `equals​(Object object)` | Returns `true` if the specified object is an envelope of the same class with equals coordinates and CRS.
    `CoordinateReferenceSystem` | `getCoordinateReferenceSystem()` | Returns the envelope coordinate reference system, or `null` if unknown.
    `int` | `getDimension()` | Returns the length of coordinate sequence (the number of entries) in this envelope.
    `double` | `getLower​(int dimension)` | Returns the limit in the direction of decreasing coordinate values in the specified dimension.
    `double` | `getMaximum​(int dimension)` | Returns the maximal coordinate value for the specified dimension.
    `double` | `getMedian​(int dimension)` | Returns the median coordinate along the specified dimension.
    `double` | `getMinimum​(int dimension)` | Returns the minimal coordinate value for the specified dimension.
    `double` | `getSpan​(int dimension)` | Returns the envelope span (typically width or height) along the specified dimension.
    `double` | `getUpper​(int dimension)` | Returns the limit in the direction of increasing coordinate values in the specified dimension.
    `int` | `hashCode()` | Returns a hash value for this envelope.
    `boolean` | `isAllNaN()` | Returns `false` if at least one coordinate value is not NaN.
    `boolean` | `isEmpty()` | Determines whether or not this envelope is empty.
    `String` | `toString()` | Formats this envelope as a "`BOX`" element.

    - ### Methods inherited from class AbstractEnvelope

      `contains, contains, contains, equals, formatTo, getLowerCorner, getMedian, getSpan, getUpperCorner, intersects, intersects, toSimpleEnvelopes`

    - ### Methods inherited from class FormattableObject

      `print, toString, toWKT`

    - ### Methods inherited from class Object

      `clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

- - ### Constructor Detail

    - #### ImmutableEnvelope

          public ImmutableEnvelope​(DirectPosition lowerCorner,
                                   DirectPosition upperCorner)
                            throws MismatchedDimensionException,
                                   MismatchedReferenceSystemException

      Constructs an envelope defined by two corners given as direct positions. The envelope CRS will be the CRS of the given positions.
      Parameters:
        `lowerCorner` - the limits in the direction of decreasing coordinate values for each dimension.
        `upperCorner` - the limits in the direction of increasing coordinate values for each dimension.
      Throws:
        `MismatchedDimensionException` - if the two positions do not have the same dimension.
        `MismatchedReferenceSystemException` - if the CRS of the two position are not equal.

    - #### ImmutableEnvelope

          public ImmutableEnvelope​(double[] lowerCorner,
                                   double[] upperCorner,
                                   CoordinateReferenceSystem crs)
                            throws MismatchedDimensionException

      Constructs an envelope defined by two corners given as sequences of coordinate values.
      Parameters:
        `lowerCorner` - the limits in the direction of decreasing coordinate values for each dimension.
        `upperCorner` - the limits in the direction of increasing coordinate values for each dimension.
        `crs` - the CRS to assign to this envelope, or `null`.
      Throws:
        `MismatchedDimensionException` - if the two sequences do not have the same length, or if the dimension of the given CRS is not equals to the dimension of the given corners.

    - #### ImmutableEnvelope

          public ImmutableEnvelope​(GeographicBoundingBox box)

      Constructs a new envelope with the same data than the specified geographic bounding box. The coordinate reference system is set to the default geographic CRS. Axis order is (longitude, latitude).
      Parameters:
        `box` - the bounding box to copy.

    - #### ImmutableEnvelope

          public ImmutableEnvelope​(Envelope envelope)

      Creates an immutable envelope with the values of the given envelope. This constructor can be used when the given envelope is known to not be an instance of `ImmutableEnvelope`. In case of doubt, consider using `castOrCopy(Envelope)` instead.
      Parameters:
        `envelope` - the envelope to copy.
      See Also:
        `castOrCopy(Envelope)`

    - #### ImmutableEnvelope

          public ImmutableEnvelope​(CoordinateReferenceSystem crs,
                                   Envelope envelope)
                            throws MismatchedDimensionException

      Creates an immutable envelope with the coordinate values of the given envelope but a different CRS. This method does not reproject the given envelope. It just assign the given CRS to this envelope without any check, except for the CRS dimension.

      The main purpose of this method is to assign a non-null CRS when the envelope to copy has a null CRS.

      Parameters:
        `crs` - the CRS to assign to this envelope, or `null`.
        `envelope` - the envelope from which to copy coordinate values.
      Throws:
        `MismatchedDimensionException` - if the dimension of the given CRS is not equals to the dimension of the given envelope.

    - #### ImmutableEnvelope

          public ImmutableEnvelope​(CoordinateReferenceSystem crs,
                                   CharSequence wkt)
                            throws IllegalArgumentException,
                                   MismatchedDimensionException

      Constructs a new envelope initialized to the values parsed from the given string in `BOX` or Well Known Text (WKT) format. The given string is typically a `BOX` element like below:

      >     BOX(-180 -90, 180 90)

      However this constructor is lenient to other geometry types like `POLYGON`. See the javadoc of the `GeneralEnvelope` constructor for more information.
      Parameters:
        `crs` - the coordinate reference system, or `null` if none.
        `wkt` - the `BOX`, `POLYGON` or other kind of element to parse.
      Throws:
        `IllegalArgumentException` - if the given string can not be parsed.
        `MismatchedDimensionException` - if the dimension of the given CRS is not equals to the dimension of the parsed envelope.

  - ### Method Detail

    - #### castOrCopy

          public static ImmutableEnvelope castOrCopy​(Envelope envelope)

      Returns the given envelope as an `ImmutableEnvelope` instance. If the given envelope is already an instance of `ImmutableEnvelope`, then it is returned unchanged. Otherwise the coordinate values and the CRS of the given envelope are copied in a new envelope.
      Parameters:
        `envelope` - the envelope to cast, or `null`.
      Returns:
        the values of the given envelope as an `ImmutableEnvelope` instance.
      See Also:
        `AbstractEnvelope​.castOrCopy(Envelope)`, `GeneralEnvelope​.castOrCopy(Envelope)`

    - #### getDimension

          public int getDimension()

      Returns the length of coordinate sequence (the number of entries) in this envelope. This information is available even when the coordinate reference system is unknown.
      Specified by:
        `getDimension` in interface `Envelope`
      Returns:
        the dimensionality of this envelope.

    - #### getCoordinateReferenceSystem

          public CoordinateReferenceSystem getCoordinateReferenceSystem()

      Returns the envelope coordinate reference system, or `null` if unknown. If non-null, it shall be the same as lower corner and upper corner CRS.
      Specified by:
        `getCoordinateReferenceSystem` in interface `Envelope`
      Returns:
        the envelope CRS, or `null` if unknown.

    - #### getLower

          public double getLower​(int dimension)
                          throws IndexOutOfBoundsException

      Returns the limit in the direction of decreasing coordinate values in the specified dimension. This is usually the algebraic minimum, except if this envelope spans the anti-meridian.
      Specified by:
        `getLower` in class `AbstractEnvelope`
      Parameters:
        `dimension` - the dimension for which to obtain the coordinate value.
      Returns:
        the starting coordinate value at the given dimension.
      Throws:
        `IndexOutOfBoundsException` - if the given index is negative or is equals or greater than the envelope dimension.

    - #### getUpper

          public double getUpper​(int dimension)
                          throws IndexOutOfBoundsException

      Returns the limit in the direction of increasing coordinate values in the specified dimension. This is usually the algebraic maximum, except if this envelope spans the anti-meridian.
      Specified by:
        `getUpper` in class `AbstractEnvelope`
      Parameters:
        `dimension` - the dimension for which to obtain the coordinate value.
      Returns:
        the starting coordinate value at the given dimension.
      Throws:
        `IndexOutOfBoundsException` - if the given index is negative or is equals or greater than the envelope dimension.

    - #### getMinimum

          public double getMinimum​(int dimension)
                            throws IndexOutOfBoundsException

      Returns the minimal coordinate value for the specified dimension. In the typical case of non-empty envelopes not spanning the anti-meridian, this method returns the `AbstractEnvelope​.getLower(int)` value verbatim. In the case of envelope spanning the anti-meridian, this method returns the axis minimum value. If the range in the given dimension is invalid, then this method returns `NaN`.
      Specified by:
        `getMinimum` in interface `Envelope`
      Overrides:
        `getMinimum` in class `AbstractEnvelope`
      Parameters:
        `dimension` - the dimension for which to obtain the coordinate value.
      Returns:
        the minimal coordinate value at the given dimension.
      Throws:
        `IndexOutOfBoundsException` - if the given index is negative or is equals or greater than the envelope dimension.

    - #### getMaximum

          public double getMaximum​(int dimension)
                            throws IndexOutOfBoundsException

      Returns the maximal coordinate value for the specified dimension. In the typical case of non-empty envelopes not spanning the anti-meridian, this method returns the `AbstractEnvelope​.getUpper(int)` value verbatim. In the case of envelope spanning the anti-meridian, this method returns the axis maximum value. If the range in the given dimension is invalid, then this method returns `NaN`.
      Specified by:
        `getMaximum` in interface `Envelope`
      Overrides:
        `getMaximum` in class `AbstractEnvelope`
      Parameters:
        `dimension` - the dimension for which to obtain the coordinate value.
      Returns:
        the maximal coordinate value at the given dimension.
      Throws:
        `IndexOutOfBoundsException` - if the given index is negative or is equals or greater than the envelope dimension.

    - #### getMedian

          public double getMedian​(int dimension)
                           throws IndexOutOfBoundsException

      Returns the median coordinate along the specified dimension. In most cases, the result is equals (minus rounding error) to:

      >     median = (getUpper(dimension) + getLower(dimension)) / 2;

      Spanning the anti-meridian of a Geographic CRS
      If upper < lower and the range meaning for the requested dimension is wraparound, then the median calculated above is actually in the middle of the space outside the envelope. In such cases, this method shifts the median value by half of the periodicity (180° in the longitude case) in order to switch from outer space to inner space. If the axis range meaning is not `WRAPAROUND`, then this method returns `NaN`.
      Specified by:
        `getMedian` in interface `Envelope`
      Overrides:
        `getMedian` in class `AbstractEnvelope`
      Parameters:
        `dimension` - the dimension for which to obtain the coordinate value.
      Returns:
        the median coordinate at the given dimension, or `Double​.NaN`.
      Throws:
        `IndexOutOfBoundsException` - if the given index is negative or is equals or greater than the envelope dimension.

    - #### getSpan

          public double getSpan​(int dimension)
                         throws IndexOutOfBoundsException

      Returns the envelope span (typically width or height) along the specified dimension. In most cases, the result is equals (minus rounding error) to:

      >     span = getUpper(dimension) - getLower(dimension);

      Spanning the anti-meridian of a Geographic CRS
      If upper < lower and the range meaning for the requested dimension is wraparound, then the span calculated above is negative. In such cases, this method adds the periodicity (typically 360° of longitude) to the span. If the result is a positive number, it is returned. Otherwise this method returns `NaN`.
      Specified by:
        `getSpan` in interface `Envelope`
      Overrides:
        `getSpan` in class `AbstractEnvelope`
      Parameters:
        `dimension` - the dimension for which to obtain the span.
      Returns:
        the span (typically width or height) at the given dimension, or `Double​.NaN`.
      Throws:
        `IndexOutOfBoundsException` - if the given index is negative or is equals or greater than the envelope dimension.

    - #### isEmpty

          public boolean isEmpty()

      Determines whether or not this envelope is empty. An envelope is empty if it has zero dimension, or if the span of at least one axis is negative, 0 or `NaN`.
      Note: Strictly speaking, there is an ambiguity if a span is `NaN` or if the envelope contains both 0 and infinite spans (since 0⋅∞ = `NaN`). In such cases, this method arbitrarily ignores the infinite values and returns `true`.
      If `isEmpty()` returns `false`, then `AbstractEnvelope​.isAllNaN()` is guaranteed to also return `false`. However the converse is not always true.
      Specified by:
        `isEmpty` in interface `Emptiable`
      Overrides:
        `isEmpty` in class `AbstractEnvelope`
      Returns:
        `true` if this envelope is empty.
      See Also:
        `DefaultGeographicBoundingBox​.isEmpty()`, `RectangularShape​.isEmpty()`

    - #### isAllNaN

          public boolean isAllNaN()

      Returns `false` if at least one coordinate value is not NaN. This `isAllNaN()` check is different than the `AbstractEnvelope​.isEmpty()` check since it returns `false` for a partially initialized envelope, while `isEmpty()` returns `false` only after all dimensions have been initialized. More specifically, the following rules apply:
      - If `isAllNaN() == true`, then `isEmpty() == true`
      - If `isEmpty() == false`, then `isAllNaN() == false`
      - The converse of the above-cited rules are not always true.
      Note that an all-NaN envelope can still have a non-null coordinate reference system.
      Overrides:
        `isAllNaN` in class `AbstractEnvelope`
      Returns:
        `true` if this envelope has NaN values.
      See Also:
        `GeneralEnvelope​.setToNaN()`, `DefaultGeographicBoundingBox​.isEmpty()`

    - #### hashCode

          public int hashCode()

      Returns a hash value for this envelope.
      Overrides:
        `hashCode` in class `AbstractEnvelope`

    - #### equals

          public boolean equals​(Object object)

      Returns `true` if the specified object is an envelope of the same class with equals coordinates and CRS.
      Implementation note: This implementation requires that the provided `object` argument is of the same class than this envelope. We do not relax this rule since not every implementations in the SIS code base follow the same contract.
      Overrides:
        `equals` in class `AbstractEnvelope`
      Parameters:
        `object` - the object to compare with this envelope.
      Returns:
        `true` if the given object is equal to this envelope.

    - #### toString

          public String toString()

      Formats this envelope as a "`BOX`" element. The output is of the form "`BOX` n `D(`lower corner`,`upper corner`)`" where n is the number of dimensions. The number of dimension is written only if different than 2.
      Example:
      - `BOX(-90 -180, 90 180)`
      - `BOX3D(-90 -180 0, 90 180 1)`
      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.
      This method formats the numbers as with `Double​.toString(double)` (i.e. without fixed number of fraction digits). The string returned by this method can be parsed by the `GeneralEnvelope` constructor.
      Overrides:
        `toString` in class `AbstractEnvelope`
      Returns:
        this envelope as a `BOX` or `BOX3D` (most typical dimensions) element.