# Enum Class ComparisonMode

Object
Enum<ComparisonMode>
ComparisonMode

All Implemented Interfaces:
  `Serializable`, `Comparable<ComparisonMode>`, `Constable`

public enum ComparisonMode extends Enum<ComparisonMode>
Specifies the level of strictness when comparing two `LenientComparable` objects for equality. This enumeration allows users to specify which kind of differences can be tolerated between two objects: differences in implementation class, differences in some kinds of property, or slight difference in numerical values.

This enumeration is ordered from stricter to more lenient levels:

1. `STRICT` – All attributes of the compared objects shall be strictly equal.
2. `BY_CONTRACT` – Only the attributes published in the interface contract need to be compared.
3. `IGNORE_METADATA` – Only the attributes relevant to the object functionality are compared.
4. `COMPATIBILITY` – Like `IGNORE_METADATA`, but ignore also some structural changes for historical reasons.
5. `APPROXIMATE` – Like `COMPATIBILITY`, with some tolerance threshold on numerical values.
6. `ALLOW_VARIANT` – Objects not really equal but related (e.g., CRS using different axis order).
7. `DEBUG` – Special mode for figuring out why two objects expected to be equal are not.

If two objects are equal at some level of strictness E, then they shall also be equal at all levels listed after E in the above list. For example, if two objects are equal at the `BY_CONTRACT` level, then they shall also be equal at the `IGNORE_METADATA` level but not necessarily at the `STRICT` level.

Since:
  0.3
See Also:
  - `LenientComparable​.equals(Object, ComparisonMode)`
  - `Utilities​.deepEquals(Object, Object, ComparisonMode)`

- ## Nested Class Summary

  ### Nested classes/interfaces inherited from class Enum

  `Enum​.EnumDesc<E extends Enum<E>>`

- ## Enum Constant Summary

  Enum Constants
  Enum Constant
  Description
  `ALLOW_VARIANT`
  Most but not all attributes relevant to the object functionality are compared.
  `APPROXIMATE`
  Only the attributes relevant to compatibility are compared, with some tolerance threshold on numerical values.
  `BY_CONTRACT`
  Only the attributes published in some contract (typically a GeoAPI interface) need to be compared.
  `COMPATIBILITY`
  Only the attributes relevant to the object functionality are compared, with a tolerance for some structural changes.
  `DEBUG`
  Asserts that two objects shall be approximately equal.
  `IGNORE_METADATA`
  Only the attributes relevant to the object functionality are compared.
  `STRICT`
  All attributes of the compared objects shall be strictly equal.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static ComparisonMode`
  `equalityLevel(Object o1, Object o2)`
  If the two given objects are equal according one of the modes enumerated in this class, then returns that mode.
  `boolean`
  `isApproximate()`
  Returns `true` if this comparison uses a tolerance threshold.
  `boolean`
  `isCompatibility()`
  Returns `true` if this comparison accepts structural changes for compatibility reasons.
  `boolean`
  `isIgnoringMetadata()`
  Returns `true` if this comparison ignores metadata.
  `static ComparisonMode`
  `valueOf(String name)`
  Returns the enum constant of this class with the specified name.
  `static ComparisonMode[]`
  `values()`
  Returns an array containing the constants of this enum class, in the order they are declared.

  ### Methods inherited from class Enum

  `clone, compareTo, describeConstable, equals, finalize, getDeclaringClass, hashCode, name, ordinal, toString, valueOf`

  ### Methods inherited from class Object

  `getClass, notify, notifyAll, wait, wait, wait`

- ## Enum Constant Details

  - ### STRICT

    public static final ComparisonMode STRICT
    All attributes of the compared objects shall be strictly equal. This comparison mode is equivalent to the `Object​.equals(Object)` method, and must be compliant with the contract documented in that method. In particular, this comparison mode shall be consistent with `Object​.hashCode()` and be symmetric (`A​.equals(B)` implies `B​.equals(A)`).

    #### Implementation note

    In the SIS implementations, this comparison mode usually have the following characteristics (not always, this is only typical):
    - The objects being compared need to be the same implementation class.
    - Private fields are compared directly instead of invoking public getter methods.
    See Also:
      - `Object​.equals(Object)`

  - ### BY_CONTRACT

    public static final ComparisonMode BY_CONTRACT
    Only the attributes published in some contract (typically a GeoAPI interface) need to be compared. The implementation classes do not need to be the same and some private attributes may be ignored.

    Note that this comparison mode does not guarantee `Object​.hashCode()` consistency, neither comparison symmetry (i.e. `A​.equals(B)` and `B​.equals(A)` may return different results if the `equals` methods are implemented differently).

    #### Implementation note

    In the SIS implementations, this comparison mode usually have the following characteristics (not always, this is only typical):
    - The objects being compared need to implement the same GeoAPI interfaces.
    - Public getter methods are used (no direct access to private fields).

  - ### IGNORE_METADATA

    public static final ComparisonMode IGNORE_METADATA
    Only the attributes relevant to the object functionality are compared. Attributes that are only informative can be ignored. This comparison mode is typically less strict than `BY_CONTRACT`.

    #### Application to coordinate reference systems

    If the objects being compared are `CoordinateReferenceSystem` instances, then only the properties impacting coordinate values shall be compared. Metadata like the identifiers or the domain of validity, which have no impact on the coordinates being calculated, shall be ignored.

    #### Application to coordinate operations

    If the objects being compared are `MathTransform` instances, then two transforms defined in a different way may be considered equivalent. For example, it is possible to define a Mercator projection in different ways, named "variant A", "variant B" and "variant C" in EPSG dataset, each having their own set of parameters. The `STRICT` or `BY_CONTRACT` modes shall consider two projections as equal only if their parameter values are strictly identical, while the `IGNORE_METADATA` mode can consider those objects as equivalent despite difference in the set of parameters, as long as coordinate operations still produce the same results.

    ##### Example

    A Mercator (variant B) projection with a standard parallel value of 60° produces the same results as a Mercator (variant A) projection with a scale factor value of 0.5.
    See Also:
      - `isIgnoringMetadata()`
      - `Utilities​.equalsIgnoreMetadata(Object, Object)`

  - ### COMPATIBILITY

    public static final ComparisonMode COMPATIBILITY
    Only the attributes relevant to the object functionality are compared, with a tolerance for some structural changes. The changes may exist for historical reasons, or for compatibility with common practice in other software. However, the changes should not have a practical impact on the numerical results of coordinate operations. For example, changes of input or output axis order is not accepted by this comparison mode.

    #### Application to datum ensembles

    Two Coordinate Reference Systems (CRS) may be considered compatible when one CRS is associated to a datum and the other CRS is associated to a datum ensemble, but the former can be considered as the legacy definition of the latter. This comparison mode can check, among other criteria, whether the datum and the datum ensemble share a common authority code.

    Example: `EPSG:9:4326` and `EPSG:10:4326`, which are both the same (at least conceptually) geographic CRS associated to the authority code 4326 in the EPSG geodetic dataset, but as defined in version 9 and 10 respectively of the EPSG database. They are the CRS definitions before and after the introduction of datum ensemble in the schema.

    #### Application to dynamic reference frames

    Two Reference Frames may be considered compatible despite one frame being static and the other frame being dynamic. This comparison mode can check, among other criteria, whether the two reference frames share a common authority code or have an equivalent name.

    Example: the "WGS 1972" reference frame as defined in versions 9 and 10 of EPSG database.

    Since:
      1.5
    See Also:
      - `isCompatibility()`

  - ### APPROXIMATE

    public static final ComparisonMode APPROXIMATE
    Only the attributes relevant to compatibility are compared, with some tolerance threshold on numerical values. The threshold is implementation dependent, but the current SIS implementation generally aims for a precision of 1 centimeter in the linear and angular parameter values for a planet of the size of Earth.

    #### Application to coordinate operations

    If two `MathTransform` objects are considered equal according this mode, then for any given identical source position, the two compared transforms shall compute at least approximately the same target position. A small difference is tolerated between the target coordinates calculated by the two math transforms. How small is “small” is implementation dependent — the threshold cannot be specified in the current implementation, because of the non-linear nature of map projections.
    Since:
      1.0
    See Also:
      - `isApproximate()`

  - ### ALLOW_VARIANT

    public static final ComparisonMode ALLOW_VARIANT
    Most but not all attributes relevant to the object functionality are compared. This comparison mode is equivalent to `APPROXIMATE`, except that it ignores some aspects that may differ between objects not equal but related. Below is a list of examples where the objects being compared would be considered different according the other modes such as `APPROXIMATE`, but are considered equivalent according this `ALLOW_VARIANT` mode.
    - Two Coordinate Reference Systems (CRS) with the same axes but in different order. Example: two geographic CRSs with the same attributes but with (latitude, longitude) axes in one case and (longitude, latitude) axes in the other case.
    Since:
      0.7

  - ### DEBUG

    @Debug public static final ComparisonMode DEBUG
    Asserts that two objects shall be approximately equal. The same comparison as `APPROXIMATE` is performed, except that an `AssertionError` is thrown if the two objects are not equal and assertions are enabled. The exception message and stack trace help to locate which attributes are not equal. This mode is typically used in assertions like below:

        assert Utilities.deepEquals(object1, object2, ComparisonMode.DEBUG);

    Note that a comparison in `DEBUG` mode may still return `false` without throwing an exception, since not all corner cases are tested. The exception is only intended to provide more details for some common cases.

- ## Method Details

  - ### values

    public static ComparisonMode[] values()
    Returns an array containing the constants of this enum class, in the order they are declared.
    Returns:
      an array containing the constants of this enum class, in the order they are declared

  - ### valueOf

    public static ComparisonMode valueOf(String name)
    Returns the enum constant of this class with the specified name. The string must match exactly an identifier used to declare an enum constant in this class. (Extraneous whitespace characters are not permitted.)
    Parameters:
      `name` - the name of the enum constant to be returned.
    Returns:
      the enum constant with the specified name
    Throws:
      `IllegalArgumentException` - if this enum class has no constant with the specified name
      `NullPointerException` - if the argument is null

  - ### isIgnoringMetadata

    public boolean isIgnoringMetadata()
    Returns `true` if this comparison ignores metadata. This method returns `true` for `IGNORE_METADATA`, `COMPATIBILITY`, `APPROXIMATE`, `ALLOW_VARIANT` and `DEBUG`.
    Returns:
      whether this comparison ignores metadata.
    Since:
      0.6

  - ### isCompatibility

    public boolean isCompatibility()
    Returns `true` if this comparison accepts structural changes for compatibility reasons. This method returns `true` for `COMPATIBILITY`, `APPROXIMATE`, `ALLOW_VARIANT` and `DEBUG`.
    Returns:
      whether this comparison accepts structural changes for compatibility reasons.
    Since:
      1.5

  - ### isApproximate

    public boolean isApproximate()
    Returns `true` if this comparison uses a tolerance threshold. This method returns `true` for `APPROXIMATE`, `ALLOW_VARIANT` and `DEBUG`.
    Returns:
      whether this comparison uses a tolerance threshold.
    Since:
      1.0

  - ### equalityLevel

    public static ComparisonMode equalityLevel(Object o1, Object o2)
    If the two given objects are equal according one of the modes enumerated in this class, then returns that mode. Otherwise returns `null`.

    Note: this method never return the `DEBUG` mode.

    Parameters:
      `o1` - the first object to compare, or `null`.
      `o2` - the second object to compare, or `null`.
    Returns:
      the most suitable comparison mode, or `null` if the two given objects are not equal according any mode in this enumeration.