001/*
002 *    GeoAPI - Java interfaces for OGC/ISO standards
003 *    Copyright © 2003-2024 Open Geospatial Consortium, Inc.
004 *    http://www.geoapi.org
005 *
006 *    Licensed under the Apache License, Version 2.0 (the "License");
007 *    you may not use this file except in compliance with the License.
008 *    You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *    Unless required by applicable law or agreed to in writing, software
013 *    distributed under the License is distributed on an "AS IS" BASIS,
014 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 *    See the License for the specific language governing permissions and
016 *    limitations under the License.
017 */
018package org.opengis.referencing.datum;
019
020import java.util.Date;
021import java.util.Optional;
022import java.time.temporal.Temporal;
023import org.opengis.referencing.IdentifiedObject;
024import org.opengis.metadata.extent.Extent;
025import org.opengis.util.InternationalString;
026import org.opengis.annotation.UML;
027import org.opengis.annotation.Classifier;
028import org.opengis.annotation.Stereotype;
029import org.opengis.geoapi.internal.Legacy;
030
031import static org.opengis.annotation.Obligation.*;
032import static org.opengis.annotation.Specification.*;
033
034
035/**
036 * Specifies the relationship of a coordinate system to an object.
037 * For {@linkplain org.opengis.referencing.crs.GeodeticCRS geodetic} and
038 * {@linkplain org.opengis.referencing.crs.VerticalCRS vertical} coordinate reference systems (<abbr>CRS</abbr>),
039 * the datum relates the coordinate system to the Earth or other celestial body.
040 * With other types of <abbr>CRS</abbr>s,
041 * the datum may relate the coordinate system to another physical or virtual object.
042 *
043 * <p>A datum uses a parameter or set of parameters that determine the location of the origin of the <abbr>CRS</abbr>.
044 * Each datum subtype can be associated with only specific types of
045 * {@linkplain org.opengis.referencing.cs.CoordinateSystem coordinate systems}, documented in their javadoc.</p>
046 *
047 * @author  OGC Topic 2 (for abstract model and documentation)
048 * @author  Martin Desruisseaux (IRD, Geomatys)
049 * @version 3.1
050 * @since   1.0
051 *
052 * @see org.opengis.referencing.cs.CoordinateSystem
053 * @see org.opengis.referencing.crs.CoordinateReferenceSystem
054 */
055@Classifier(Stereotype.ABSTRACT)
056@UML(identifier="Datum", specification=ISO_19111)
057public interface Datum extends IdentifiedObject {
058    /**
059     * Key for the <code>{@value}</code> property to be given to the
060     * {@code DatumFactory.createFoo(Map, ...)} methods.
061     * This is used for setting the value to be returned by {@link #getAnchorDefinition()}.
062     *
063     * @see DatumFactory
064     * @see #getAnchorDefinition()
065     *
066     * @since 3.1
067     */
068    String ANCHOR_DEFINITION_KEY = "anchorDefinition";
069
070    /**
071     * Key for the <code>{@value}</code> property to be given to the
072     * {@code DatumFactory.createFoo(Map, ...)} methods.
073     * This is used for setting the value to be returned by {@link #getAnchorDefinition()}.
074     *
075     * @see DatumFactory
076     * @see #getAnchorDefinition()
077     *
078     * @deprecated Renamed {@link #ANCHOR_DEFINITION_KEY} for conformance with ISO 19111:2019 revision.
079     */
080    @Deprecated(since = "3.1")
081    String ANCHOR_POINT_KEY = "anchorPoint";
082
083    /**
084     * Key for the <code>{@value}</code> property to be given to the
085     * {@code DatumFactory.createFoo(Map, ...)} methods.
086     * This is used for setting the value to be returned by {@link #getAnchorEpoch()}.
087     *
088     * @see DatumFactory
089     * @see #getAnchorEpoch()
090     *
091     * @since 3.1
092     */
093    String ANCHOR_EPOCH_KEY = "anchorEpoch";
094
095    /**
096     * Key for the <code>{@value}</code> property to be given to the
097     * {@code DatumFactory.createFoo(Map, ...)} methods.
098     * This is used for setting the value to be returned by {@link #getRealizationEpoch()}.
099     *
100     * @see DatumFactory
101     * @see #getRealizationEpoch()
102     *
103     * @deprecated Renamed {@link #ANCHOR_EPOCH_KEY} for conformance with ISO 19111:2019 revision.
104     */
105    @Deprecated(since = "3.1")
106    String REALIZATION_EPOCH_KEY = "realizationEpoch";
107
108    /**
109     * Key for the <code>{@value}</code> property to be given to the
110     * {@code DatumFactory.createFoo(Map, ...)} methods.
111     *
112     * @see DatumFactory
113     * @see org.opengis.referencing.ObjectDomain#getDomainOfValidity()
114     *
115     * @deprecated Moved to {@link org.opengis.referencing.ObjectDomain} as of ISO 19111:2019.
116     */
117    @Deprecated(since="3.1")
118    String DOMAIN_OF_VALIDITY_KEY = "domainOfValidity";
119
120    /**
121     * Key for the <code>{@value}</code> property to be given to the
122     * {@code DatumFactory.createFoo(Map, ...)} methods.
123     *
124     * @see DatumFactory
125     * @see org.opengis.referencing.ObjectDomain#getScope()
126     *
127     * @deprecated Moved to {@link org.opengis.referencing.ObjectDomain} as of ISO 19111:2019.
128     */
129    @Deprecated(since="3.1")
130    String SCOPE_KEY = "scope";
131
132    /**
133     * Key for the <code>{@value}</code> property to be given to the
134     * {@code DatumFactory.createFoo(Map, ...)} methods.
135     * This is used for setting the value to be returned by {@link #getPublicationDate()}.
136     *
137     * @see DatumFactory
138     * @see #getPublicationDate()
139     *
140     * @since 3.1
141     */
142    String PUBLICATION_DATE_KEY = "publicationDate";
143
144    /**
145     * Key for the <code>{@value}</code> property to be given to the
146     * {@code DatumFactory.createFoo(Map, ...)} methods.
147     * This is used for setting the value to be returned by {@link #getConventionalRS()}.
148     *
149     * @see DatumFactory
150     * @see #getConventionalRS()
151     *
152     * @since 3.1
153     */
154    String CONVENTIONAL_RS_KEY = "conventionalRS";
155
156    /**
157     * Returns a description of the relationship used to anchor the coordinate system to the Earth or alternate object.
158     * The definition may include coordinates of an identified point or points.
159     * Also known as the "origin", especially for {@link EngineeringDatum}s.
160     *
161     * <ul>
162     *   <li>For {@link GeodeticDatum}, the anchor may be a set of station coordinates.
163     *       if the reference frame is dynamic, it will also include coordinate velocities.
164     *       For a traditional geodetic datum, the anchor may be a point known as the fundamental point,
165     *       which is traditionally the point where the relationship between geoid and ellipsoid is defined,
166     *       together with a direction from that point.</li>
167     *
168     *   <li>For a {@link VerticalDatum}, the anchor may be the zero level at one or more defined locations
169     *       or a conventionally defined surface.</li>
170     *
171     *   <li>For an {@link EngineeringDatum}, the anchor may be an identified physical point
172     *       with the orientation defined relative to the object.</li>
173     * </ul>
174     *
175     * @return a description of the anchor point.
176     *
177     * @since 3.1
178     */
179    @UML(identifier="anchorDefinition", obligation=OPTIONAL, specification=ISO_19111)
180    default Optional<InternationalString> getAnchorDefinition() {
181        return Optional.empty();
182    }
183
184    /**
185     * A description of the relationship used to anchor the coordinate system to the Earth or alternate object.
186     *
187     * @return a description of the anchor point, or {@code null} if none.
188     *
189     * @deprecated Renamed {@link #getAnchorDefinition()} for conformance with ISO 19111:2019 revision.
190     */
191    @Deprecated(since = "3.1")
192    @UML(identifier="anchorPoint", obligation=OPTIONAL, specification=ISO_19111, version=2003)
193    default InternationalString getAnchorPoint() {
194        return getAnchorDefinition().orElse(null);
195    }
196
197    /**
198     * Returns the epoch at which a static datum matches a dynamic datum from which it has been derived.
199     * This time may be precise or merely a year (e.g. 1983 for NAD83). In the latter case, the epoch usually
200     * refers to the year in which a major recalculation of the geodetic control network, underlying the datum,
201     * was executed or initiated.
202     *
203     * <p>This epoch should not be confused with the frame reference epoch of dynamic reference frames.
204     * Nor with the epoch at which a reference frame is defined to be aligned with another reference frame.
205     * this information should be included in the datum {@linkplain #getAnchorDefinition() anchor definition}.</p>
206     *
207     * @return epoch at which a static datum matches a dynamic datum from which it has been derived.
208     *
209     * @see java.time.Year
210     * @see java.time.YearMonth
211     * @see java.time.LocalDate
212     *
213     * @since 3.1
214     */
215    @UML(identifier="anchorEpoch", obligation=OPTIONAL, specification=ISO_19111)
216    default Optional<Temporal> getAnchorEpoch() {
217        return Optional.empty();
218    }
219
220    /**
221     * The time after which this datum definition is valid.
222     *
223     * @return the datum realization epoch, or {@code null} if not available.
224     *
225     * @deprecated Renamed {@link #getAnchorEpoch()} for conformance with ISO 19111:2019 revision.
226     */
227    @Deprecated(since = "3.1")
228    @UML(identifier="realizationEpoch", obligation=OPTIONAL, specification=ISO_19111, version=2007)
229    default Date getRealizationEpoch() {
230        return Legacy.toDate(getAnchorEpoch().orElse(null));
231    }
232
233    /**
234     * Area or region or timeframe in which this datum is valid.
235     *
236     * @return the datum valid domain, or {@code null} if not available.
237     *
238     * @deprecated Replaced by {@link #getDomains()} as of ISO 19111:2019.
239     */
240    @Deprecated(since = "3.1")
241    @UML(identifier="domainOfValidity", obligation=OPTIONAL, specification=ISO_19111, version=2007)
242    default Extent getDomainOfValidity() {
243        return Legacy.getDomainOfValidity(getDomains());
244    }
245
246    /**
247     * Description of domain of usage, or limitations of usage, for which this datum object is valid.
248     *
249     * @return a description of domain of usage, or {@code null} if none.
250     *
251     * @departure historic
252     *   This method has been kept conformant with the specification published in 2003. The revision
253     *   published in 2007 replaced the singleton by a collection and changed the obligation
254     *   from "optional" to "mandatory", requiring a return value of <q>not known</q>
255     *   if the scope is unknown.
256     *
257     * @deprecated Replaced by {@link #getDomains()} as of ISO 19111:2019.
258     */
259    @Deprecated(since = "3.1")
260    @UML(identifier="scope", obligation=OPTIONAL, specification=ISO_19111, version=2007)
261    default InternationalString getScope() {
262        return Legacy.getScope(getDomains());
263    }
264
265    /**
266     * Returns the date on which the datum definition was published.
267     * Should be an instance of {@link java.time.LocalDate}, but other types are also allowed.
268     * For example, a publication date may be merely a {@link java.time.Year}.
269     *
270     * @return date on which the datum definition was published.
271     *
272     * @since 3.1
273     */
274    @UML(identifier="publicationDate", obligation=OPTIONAL, specification=ISO_19111)
275    default Optional<Temporal> getPublicationDate() {
276        return Optional.empty();
277    }
278
279    /**
280     * Returns the name, identifier, alias and remarks for the reference system realized by this reference frame.
281     * Examples: "ITRS" for ITRF88 through ITRF2008 and ITRF2014, or "EVRS" for EVRF2000 and EVRF2007.
282     * All datums that are members of a {@linkplain DatumEnsemble datum ensemble} shall have the same
283     * conventional reference system.
284     *
285     * @return reference system realized by this reference frame.
286     *
287     * @since 3.1
288     */
289    @UML(identifier="conventionalRS", obligation=OPTIONAL, specification=ISO_19111)
290    default Optional<IdentifiedObject> getConventionalRS() {
291        return Optional.empty();
292    }
293}