Class DefaultCompoundCRS

All Implemented Interfaces:
Serializable, Formattable, Deprecable, LenientComparable, org.opengis.referencing.crs.CompoundCRS, org.opengis.referencing.crs.CoordinateReferenceSystem, org.opengis.referencing.IdentifiedObject, org.opengis.referencing.ReferenceSystem

public class DefaultCompoundCRS extends AbstractCRS implements org.opengis.referencing.crs.CompoundCRS
A CRS describing the position of points through two or more independent coordinate reference systems. This class is often used for defining 4-dimensional (x,y,z,t) coordinate reference systems as an aggregation of simpler CRS. Below is two examples of such aggregations:

Flat list

CompoundCRS — (x, y, z, t)
  ├─ProjectedCRS — (x, y)
  ├─VerticalCRS — (z)
  └─TemporalCRS — (t)

Hierarchical structure

CompoundCRS — (x, y, z, t)
  ├─CompoundCRS — (x, y, z)
  │   ├─ProjectedCRS — (x, y)
  │   └─VerticalCRS — (z)
  └─TemporalCRS — (t)
Strictly speaking, only the flat list on the left side is allowed by OGC/ISO specifications. However, Apache SIS relaxes this rule by allowing hierarchies as shown on the right side. This flexibility allows SIS to preserve information about the (x,y,z) part (e.g. the EPSG identifier) that would otherwise been lost. Users can obtain the list of their choice by invoking getSingleComponents() or getComponents() respectively.

Component order

ISO 19162 restricts compound CRS to the following components in that order:
  • A mandatory horizontal CRS (only one of two-dimensional GeographicCRS or ProjectedCRS or EngineeringCRS).
  • Optionally followed by a VerticalCRS or a ParametricCRS (but not both).
  • Optionally followed by a TemporalCRS.
SIS currently does not enforce those restrictions. In particular:
  • Components may appear in different order.
  • VerticalCRS + TemporalCRS (without horizontal component) is accepted.
  • GeocentricCRS or three-dimensional GeographicCRS can be combined with TemporalCRS.
However, users are encouraged to follow ISO 19162 restriction for better portability.

Immutability and thread safety

This class is immutable and thus thread-safe if the property values (not necessarily the map itself) and all CoordinateReferenceSystem instances given to the constructor are also immutable. Unless otherwise noted in the javadoc, this condition holds if all components were created using only SIS factories and static constants.
Since:
0.4
Version:
0.8
See Also:
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private List<? extends org.opengis.referencing.crs.CoordinateReferenceSystem>
    The coordinate reference systems in this compound CRS.
    private static final long
    Serial number for inter-operability with different versions.
    private List<org.opengis.referencing.crs.SingleCRS>
    A decomposition of the CRS list into the single elements.

    Fields inherited from class org.apache.sis.referencing.AbstractIdentifiedObject

    DEPRECATED_KEY, LOCALE_KEY

    Fields inherited from interface org.opengis.referencing.IdentifiedObject

    ALIAS_KEY, IDENTIFIERS_KEY, NAME_KEY, REMARKS_KEY

    Fields inherited from interface org.opengis.referencing.ReferenceSystem

    DOMAIN_OF_VALIDITY_KEY, SCOPE_KEY
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    Constructs a new object in which every attributes are set to a null or empty value.
     
    DefaultCompoundCRS(Map<String,?> properties, org.opengis.referencing.crs.CoordinateReferenceSystem... components)
    Constructs a compound CRS from the given properties and CRS.
    protected
    DefaultCompoundCRS(org.opengis.referencing.crs.CompoundCRS crs)
    Constructs a new coordinate reference system with the same values than the specified one.
  • Method Summary

    Modifier and Type
    Method
    Description
    castOrCopy(org.opengis.referencing.crs.CompoundCRS object)
    Returns a SIS CRS implementation with the same values than the given arbitrary implementation.
    protected long
    Invoked by hashCode() for computing the hash code when first needed.
    private static org.opengis.referencing.cs.CoordinateSystem
    createCoordinateSystem(Map<String,?> properties, org.opengis.referencing.crs.CoordinateReferenceSystem[] components)
    Returns a compound coordinate system for the specified array of CRS objects.
    (package private) final AbstractCRS
    createSameType(Map<String,?> properties, org.opengis.referencing.cs.CoordinateSystem cs)
    Should never be invoked since we override AbstractCRS.forConvention(AxesConvention).
    boolean
    equals(Object object, ComparisonMode mode)
    Compares this coordinate reference system with the specified object for equality.
    Returns a coordinate reference system equivalent to this one but with axes rearranged according the given convention.
    protected String
    formatTo(Formatter formatter)
    Formats this CRS as a Well Known Text CompoundCRS[…] element.
    List<org.opengis.referencing.crs.CoordinateReferenceSystem>
    Returns the ordered list of coordinate reference systems.
    (package private) final org.opengis.referencing.datum.Datum
    Compound CRS do not have datum.
    Class<? extends org.opengis.referencing.crs.CompoundCRS>
    Returns the GeoAPI interface implemented by this class.
    List<org.opengis.referencing.crs.SingleCRS>
    Returns the ordered list of single coordinate reference systems.
    private org.opengis.referencing.crs.CoordinateReferenceSystem[]
    Returns the CRS components to marshal.
    (package private) static boolean
    isStandardCompliant(List<? extends org.opengis.referencing.crs.CoordinateReferenceSystem> singles)
    Returns true if the sequence of single components is conform to the ISO 19162 restrictions.
    private void
    Computes the single CRS list on deserialization.
    private void
    setComponents(List<? extends org.opengis.referencing.crs.CoordinateReferenceSystem> crs)
    Computes the components and singles fields from the given CRS list.
    private boolean
    setSingleComponents(List<? extends org.opengis.referencing.crs.CoordinateReferenceSystem> crs)
    Computes the singles field from the given CRS list and returns true if the given list was already a list of single CRS.
    private void
    setXMLComponents(org.opengis.referencing.crs.CoordinateReferenceSystem[] crs)
    Invoked by JAXB for setting the components of this compound CRS.
    private static void
    verify(Map<String,?> properties, org.opengis.referencing.crs.CoordinateReferenceSystem[] components)
    Verifies that the given array does not contain duplicated horizontal or vertical components.

    Methods inherited from class org.apache.sis.referencing.crs.AbstractCRS

    castOrCopy, formatCS, getCached, getCoordinateSystem, getCoordinateSystem, isBaseCRS, setCached, setCoordinateSystem

    Methods inherited from class org.apache.sis.referencing.AbstractReferenceSystem

    getDomainOfValidity, getScope

    Methods inherited from class org.apache.sis.io.wkt.FormattableObject

    print, toString, toString, toWKT

    Methods inherited from class java.lang.Object

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

    Methods inherited from interface org.opengis.referencing.crs.CoordinateReferenceSystem

    getCoordinateSystem

    Methods inherited from interface org.opengis.referencing.IdentifiedObject

    getAlias, getIdentifiers, getName, getRemarks, toWKT

    Methods inherited from interface org.opengis.referencing.ReferenceSystem

    getDomainOfValidity, getScope
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      Serial number for inter-operability with different versions.
      See Also:
    • components

      private List<? extends org.opengis.referencing.crs.CoordinateReferenceSystem> components
      The coordinate reference systems in this compound CRS. May be the same reference than singles.

      Consider this field as final! This field is modified only at construction and unmarshalling time by setComponents(List)

    • singles

      private transient List<org.opengis.referencing.crs.SingleCRS> singles
      A decomposition of the CRS list into the single elements. Computed by setSingleComponents(List) on construction, deserialization or unmarshalling.
  • Constructor Details

    • DefaultCompoundCRS

      public DefaultCompoundCRS(Map<String,?> properties, org.opengis.referencing.crs.CoordinateReferenceSystem... components)
      Constructs a compound CRS from the given properties and CRS. The properties given in argument follow the same rules than for the super-class constructor. The following table is a reminder of main (not all) properties:
      Recognized properties (non exhaustive list)
      Property name Value type Returned by
      "name" ReferenceIdentifier or String AbstractIdentifiedObject.getName()
      "alias" GenericName or CharSequence (optionally as array) AbstractIdentifiedObject.getAlias()
      "identifiers" ReferenceIdentifier (optionally as array) AbstractIdentifiedObject.getIdentifiers()
      "remarks" InternationalString or String AbstractIdentifiedObject.getRemarks()
      "domainOfValidity" Extent AbstractReferenceSystem.getDomainOfValidity()
      "scope" InternationalString or String AbstractReferenceSystem.getScope()
      Parameters:
      properties - the properties to be given to the coordinate reference system.
      components - the sequence of coordinate reference systems making this compound CRS.
      Throws:
      IllegalArgumentException - if the given array does not contain at least two components, or if two consecutive components are a geographic CRS with an ellipsoidal height.
      See Also:
    • DefaultCompoundCRS

      protected DefaultCompoundCRS(org.opengis.referencing.crs.CompoundCRS crs)
      Constructs a new coordinate reference system with the same values than the specified one. This copy constructor provides a way to convert an arbitrary implementation into a SIS one or a user-defined one (as a subclass), usually in order to leverage some implementation-specific API.

      This constructor performs a shallow copy, i.e. the properties are not cloned.

      Parameters:
      crs - the coordinate reference system to copy.
    • DefaultCompoundCRS

      private DefaultCompoundCRS()
      Constructs a new object in which every attributes are set to a null or empty value. This is not a valid object. This constructor is strictly reserved to JAXB, which will assign values to the fields using reflection.
  • Method Details

    • verify

      private static void verify(Map<String,?> properties, org.opengis.referencing.crs.CoordinateReferenceSystem[] components)
      Verifies that the given array does not contain duplicated horizontal or vertical components. Verifies also that if there is an horizontal component, then there is no ellipsoidal height defined separately.
      Parameters:
      properties - the user-specified properties, for determining the locale of error messages.
      components - the components to verify.
    • createCoordinateSystem

      private static org.opengis.referencing.cs.CoordinateSystem createCoordinateSystem(Map<String,?> properties, org.opengis.referencing.crs.CoordinateReferenceSystem[] components)
      Returns a compound coordinate system for the specified array of CRS objects.
      Parameters:
      properties - the properties given to the constructor, or null if unknown.
      components - the CRS components, usually singles but not necessarily.
      Returns:
      the coordinate system for the given components.
    • castOrCopy

      public static DefaultCompoundCRS castOrCopy(org.opengis.referencing.crs.CompoundCRS object)
      Returns a SIS CRS implementation with the same values than the given arbitrary implementation. If the given object is null, then this method returns null. Otherwise if the given object is already a SIS implementation, then the given object is returned unchanged. Otherwise a new SIS implementation is created and initialized to the attribute values of the given object.
      Parameters:
      object - the object to get as a SIS implementation, or null if none.
      Returns:
      a SIS implementation containing the values of the given object (may be the given object itself), or null if the argument was null.
    • getInterface

      public Class<? extends org.opengis.referencing.crs.CompoundCRS> getInterface()
      Returns the GeoAPI interface implemented by this class. The SIS implementation returns CompoundCRS.class.
      Note for implementers: Subclasses usually do not need to override this method since GeoAPI does not define CompoundCRS sub-interface. Overriding possibility is left mostly for implementers who wish to extend GeoAPI with their own set of interfaces.
      Overrides:
      getInterface in class AbstractCRS
      Returns:
      CompoundCRS.class or a user-defined sub-interface.
    • getDatum

      final org.opengis.referencing.datum.Datum getDatum()
      Compound CRS do not have datum.
      Overrides:
      getDatum in class AbstractCRS
      Returns:
      the datum, or null if none.
    • getComponents

      public List<org.opengis.referencing.crs.CoordinateReferenceSystem> getComponents()
      Returns the ordered list of coordinate reference systems. This is the list of CRS given at construction time. This list may contains other CompoundCRS instances, as described in class Javadoc. For a flattened list of SingleCRS instances, see getSingleComponents().
      Specified by:
      getComponents in interface org.opengis.referencing.crs.CompoundCRS
      Returns:
      the coordinate reference systems as an unmodifiable list.
    • setComponents

      private void setComponents(List<? extends org.opengis.referencing.crs.CoordinateReferenceSystem> crs)
      Computes the components and singles fields from the given CRS list. If the two lists have the same content, then the two fields will reference the same list.
      See Also:
    • getSingleComponents

      public List<org.opengis.referencing.crs.SingleCRS> getSingleComponents()
      Returns the ordered list of single coordinate reference systems. If this compound CRS contains other compound CRS, then all of them are flattened in a sequence of SingleCRS objects. See class Javadoc for more information.
      Returns:
      the single coordinate reference systems as an unmodifiable list.
      See Also:
    • setSingleComponents

      private boolean setSingleComponents(List<? extends org.opengis.referencing.crs.CoordinateReferenceSystem> crs)
      Computes the singles field from the given CRS list and returns true if the given list was already a list of single CRS.

      WARNING: this method is invoked by before the components field is set. Do not use that field in this method.

      See Also:
    • readObject

      private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
      Computes the single CRS list on deserialization.
      Parameters:
      in - the input stream from which to deserialize a compound CRS.
      Throws:
      IOException - if an I/O error occurred while reading or if the stream contains invalid data.
      ClassNotFoundException - if the class serialized on the stream is not on the classpath.
    • isStandardCompliant

      static boolean isStandardCompliant(List<? extends org.opengis.referencing.crs.CoordinateReferenceSystem> singles)
      Returns true if the sequence of single components is conform to the ISO 19162 restrictions. The WKT 2 specification at §16.1 restricts CompoundCRS to the following components in that order:
      • A mandatory horizontal CRS (only one of two-dimensional GeographicCRS or ProjectedCRS or EngineeringCRS).
      • Optionally followed by a VerticalCRS or a ParametricCRS (but not both).
      • Optionally followed by a TemporalCRS.
      This method verifies the above criteria with the following flexibilities:
      • Accepts three-dimensional GeodeticCRS followed by a TemporalCRS.
      This method does not verify recursively if the component are themselves standard compliant. In particular, this method does not verify if the geographic CRS uses (latitude, longitude) axes order as requested by ISO 19162.

      This method is not yet public because of the above-cited limitations: a true return value is not a guarantee that the CRS is really standard-compliant.

      Returns:
      true if this CRS is "standard" compliant, except for the above-cited limitations.
    • forConvention

      public DefaultCompoundCRS forConvention(AxesConvention convention)
      Returns a coordinate reference system equivalent to this one but with axes rearranged according the given convention. If this CRS is already compatible with the given convention, then this method returns this.

      If the given convention is AxesConvention.DISPLAY_ORIENTED or AxesConvention.NORMALIZED, then this method will also reorder the components with horizontal CRS (geodetic or projected) first, then vertical CRS, then temporal CRS.

      Overrides:
      forConvention in class AbstractCRS
      Parameters:
      convention - the axes convention for which a coordinate reference system is desired.
      Returns:
      a coordinate reference system compatible with the given convention (may be this).
      See Also:
    • createSameType

      final AbstractCRS createSameType(Map<String,?> properties, org.opengis.referencing.cs.CoordinateSystem cs)
      Should never be invoked since we override AbstractCRS.forConvention(AxesConvention).
      Overrides:
      createSameType in class AbstractCRS
    • equals

      public boolean equals(Object object, ComparisonMode mode)
      Compares this coordinate reference system with the specified object for equality.
      Specified by:
      equals in interface LenientComparable
      Overrides:
      equals in class AbstractCRS
      Parameters:
      object - the object to compare to this.
      mode - STRICT for performing a strict comparison, or IGNORE_METADATA for comparing only properties relevant to transformations.
      Returns:
      true if both objects are equal.
      See Also:
    • computeHashCode

      protected long computeHashCode()
      Invoked by hashCode() for computing the hash code when first needed. See AbstractIdentifiedObject.computeHashCode() for more information.
      Overrides:
      computeHashCode in class AbstractCRS
      Returns:
      the hash code value. This value may change in any future Apache SIS version.
    • formatTo

      protected String formatTo(Formatter formatter)
      Formats this CRS as a Well Known Text CompoundCRS[…] element.

      WKT validity

      The WKT version 2 format restricts compound CRS to the following components in that order:
      • A mandatory horizontal CRS (only one of two-dimensional GeographicCRS or ProjectedCRS or EngineeringCRS).
      • Optionally followed by a VerticalCRS or a ParametricCRS (but not both).
      • Optionally followed by a TemporalCRS.
      SIS does not check if this CRS is compliant with the above-cited restrictions.
      Overrides:
      formatTo in class AbstractCRS
      Parameters:
      formatter - the formatter where to format the inner content of this WKT element.
      Returns:
      "CompoundCRS" (WKT 2) or "Compd_CS" (WKT 1).
      See Also:
    • getXMLComponents

      private org.opengis.referencing.crs.CoordinateReferenceSystem[] getXMLComponents()
      Returns the CRS components to marshal. We use this private methods instead of annotating getSingleComponents() directly for two reasons:
      • Use array instead of List in order to force JAXB to invoke the setter method. This setter is needed for performing additional work after setting the list of CRS.
      • Allow a slightly asymmetry: marshal SingleCRS components for compliance with the standard, but accept the more generic CoordinateReferenceSystem elements at unmarshalling time.
    • setXMLComponents

      private void setXMLComponents(org.opengis.referencing.crs.CoordinateReferenceSystem[] crs)
      Invoked by JAXB for setting the components of this compound CRS.