/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2008, Open Source Geospatial Foundation (OSGeo) * (C) 2014, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.temporal.reference; import java.util.Collection; import java.util.Map; import java.util.Objects; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.ComparisonMode; import org.opengis.referencing.cs.TimeCS; import org.opengis.referencing.datum.TemporalDatum; import org.opengis.temporal.OrdinalEra; import org.opengis.temporal.OrdinalReferenceSystem; /** * <p>An {@linkplain OrdinalReferenceSystem Ordinal Reference System} is based on an ordinal scale. * In its simpliest form, an ordinal temporal reference system is an ordered series of events. * Generally a specific series of events is associated with a single location. * Temporal relationships between different locations can be determinate only to the degree * that events at one location can be correlated with events at other locations on the basis * of non-temporal characteristics of the events. Such correlation can be used to develop a * more broadly based temporal reference system define in terms of periods within which similar * events have occured. The term {@linkplain OrdinalEra ordinal era} is use in this standard to * refer to such a period.</p> * * <blockquote><font size="-1">An {@linkplain OrdinalReferenceSystem Ordinal Temporal Reference System} * consists of a set of {@linkplain OrdinalEra ordinal era}. {@linkplain OrdinalReferenceSystem Ordinal Reference System} * are often hierarchically structured such that an {@linkplain OrdinalEra ordinal era} at a given * level of hierarchy includes a sequence of coterminous shorter {@linkplain OrdinalEra ordinal era}</font></blockquote> * * @author Mehdi Sidhoum (Geomatys) * @author Remi Marechal (Geomatys) * @module * * @version 4.0 * @since 4.0 */ @XmlType(name = "TimeOrdinalReferenceSystem_Type", propOrder = { "ordinalEraSequence" }) @XmlRootElement(name = "TimeOrdinalReferenceSystem") public class DefaultOrdinalReferenceSystem extends DefaultTemporalReferenceSystem implements OrdinalReferenceSystem { /** * An ordinal temporal reference system consists of a set of ordinal eras, * that make up the highest level of hierarchy. */ private final Collection<OrdinalEra> ordinalEraSequence; /** * Create a default {@link OrdinalReferenceSystem} implementation initialize with the given parameters. * * The properties given in argument follow the same rules than for the * {@linkplain DefaultTemporalReferenceSystem#DefaultTemporalReferenceSystem(java.util.Map, org.opengis.referencing.datum.TemporalDatum, org.opengis.referencing.cs.TimeCS) super-class constructor}. * * <table class="ISO 19108"> * <caption>Recognized properties (non exhaustive list)</caption> * <tr> * <th>Property name</th> * <th>Value type</th> * <th>Returned by</th> * </tr> * <tr> * <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td> * <td>{@link org.opengis.referencing.ReferenceIdentifier} or {@link String}</td> * <td>{@link #getName()}</td> * </tr> * <tr> * <td>{@value org.opengis.referencing.datum.Datum#DOMAIN_OF_VALIDITY_KEY}</td> * <td>{@link org.opengis.metadata.extent.Extent}</td> * <td>{@link #getDomainOfValidity()}</td> * </tr> * <tr> * <td>{@value org.opengis.temporal.Calendar#REFERENCE_EVENT_KEY}</td> * <td>{@link org.opengis.util.InternationalString}</td> * <td>{@link #getReferenceEvent()}</td> * </tr> * </table> * * @param properties The properties to be given to the coordinate reference system. * @param datum The datum. * @param cs The coordinate system. * @param ordinalEraSequence A hierarchically-structured collection of {@linkplain OrdinalEra ordinal era}. */ public DefaultOrdinalReferenceSystem(Map<String, ?> properties, Collection<OrdinalEra> ordinalEraSequence) { super(properties); ArgumentChecks.ensureNonNull("ordinalEraSequence", ordinalEraSequence); this.ordinalEraSequence = ordinalEraSequence; } /** * Empty constructor only use during XML binding. */ private DefaultOrdinalReferenceSystem() { ordinalEraSequence = null; } /** * Constructs a new instance initialized with the values from the specified metadata object. * This is a <cite>shallow</cite> copy constructor, since the other metadata contained in the * given object are not recursively copied. * * @param object The OrdinalReferenceSystem to copy values from, or {@code null} if none. * * @see #castOrCopy(OrdinalReferenceSystem) */ public DefaultOrdinalReferenceSystem(final OrdinalReferenceSystem object) { super(object); if (object != null) { Collection<OrdinalEra> ordinalEraSeq = (Collection<OrdinalEra>) object.getComponents(); ArgumentChecks.ensureNonNull("ordinalEraSequence", ordinalEraSeq); this.ordinalEraSequence = ordinalEraSeq; } else { ordinalEraSequence = null; //-- maybe an exception } } /** * Returns a Geotk implementation with the values of the given arbitrary implementation. * This method performs the first applicable action in the following choices: * * <ul> * <li>If the given object is {@code null}, then this method returns {@code null}.</li> * <li>Otherwise if the given object is already an instance of * {@code DefaultOrdinalReferenceSystem}, then it is returned unchanged.</li> * <li>Otherwise a new {@code DefaultOrdinalReferenceSystem} instance is created using the * {@linkplain #DefaultOrdinalReferenceSystem(OrdinalReferenceSystem) copy constructor} * and returned. Note that this is a <cite>shallow</cite> copy operation, since the other * metadata contained in the given object are not recursively copied.</li> * </ul> * * @param object The object to get as a Geotk implementation, or {@code null} if none. * @return A Geotk implementation containing the values of the given object (may be the * given object itself), or {@code null} if the argument was null. */ public static DefaultOrdinalReferenceSystem castOrCopy(final OrdinalReferenceSystem object) { if (object == null || object instanceof DefaultTemporalCoordinateSystem) { return (DefaultOrdinalReferenceSystem) object; } return new DefaultOrdinalReferenceSystem(object); } /** * Returns the set of ordinal eras of which this ordinal reference system consists of. * <blockquote><font size="-1">{@linkplain OrdinalEra ordinal era} that make up the * highest level of hierarchy.</font></blockquote> * * @return A hierarchically-structured collection of {@linkplain OrdinalEra ordinal era}. */ @Override @XmlElement(name = "component", required = true) public Collection<OrdinalEra> getComponents() { return ordinalEraSequence; } /** * {@inheritDoc } */ @Override public boolean equals(Object object, ComparisonMode mode) { if (object == this) return true; final boolean sup = super.equals(object, mode); if (!sup) return false; if (object instanceof DefaultOrdinalReferenceSystem && super.equals(object)) { final DefaultOrdinalReferenceSystem that = (DefaultOrdinalReferenceSystem) object; return Objects.equals(this.ordinalEraSequence, that.ordinalEraSequence); } return false; } /** * {@inheritDoc } */ @Override protected long computeHashCode() { return 37 * getName().hashCode() * (this.ordinalEraSequence != null ? this.ordinalEraSequence.hashCode() : 0); } /** * {@inheritDoc } */ @Override public String toString() { StringBuilder s = new StringBuilder(super.toString()).append('\n').append("OrdinalReferenceSystem:").append('\n'); if (ordinalEraSequence != null) { s.append("ordinalEraSequence:").append(ordinalEraSequence).append('\n'); } return super.toString().concat("\n").concat(s.toString()); } }