001/*
002 *    GeoAPI - Java interfaces for OGC/ISO standards
003 *    Copyright © 2004-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;
019
020import java.util.Set;
021import java.util.Collection;
022import java.util.Collections;
023import org.opengis.util.GenericName;
024import org.opengis.util.InternationalString;
025import org.opengis.metadata.Identifier;
026import org.opengis.annotation.UML;
027import org.opengis.annotation.Classifier;
028import org.opengis.annotation.Stereotype;
029
030import static org.opengis.annotation.Obligation.*;
031import static org.opengis.annotation.Specification.*;
032
033
034/**
035 * Identification and remarks information for a reference system or CRS-related object.
036 * Identified objects contain the following properties:
037 *
038 * <ul>
039 *   <li>A {@linkplain #getName() name} (e.g. <q>North American Datum of 1983</q>).</li>
040 *   <li>Alternative names or {@linkplain #getAlias() aliases} (e.g. <q>NAD83</q> abbreviation).</li>
041 *   <li>{@linkplain #getIdentifiers() Identifiers} allocated by authorities
042 *       (e.g. a register of geodetic codes and parameters might give the NAD83 datum a unique code of <q>6269</q>).</li>
043 *   <li>{@linkplain #getRemarks() Remarks} about this object, including data source information.</li>
044 * </ul>
045 *
046 * Some typical {@code IdentifiedObject} sub-types are:
047 *
048 * <ul>
049 *   <li>{@linkplain org.opengis.referencing.datum.GeodeticDatum Geodetic Reference Frame} (e.g. <cite>World Geodetic System 1984</cite>),</li>
050 *   <li>{@linkplain org.opengis.referencing.operation.OperationMethod Operation Method} (e.g. <cite>Mercator (variant A)</cite>),</li>
051 *   <li>{@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem Coordinate Reference System} (e.g. <cite>WGS 84 / World Mercator</cite>).</li>
052 * </ul>
053 *
054 * When {@link org.opengis.referencing.crs.CRSAuthorityFactory} is used to create an object,
055 * the {@linkplain Identifier#getAuthority() authority} and {@linkplain Identifier#getCode()
056 * authority code} values shall be set to the authority name of the factory object,
057 * and the authority code supplied by the client, respectively.
058 * The other values may or may not be set.
059 * If the authority is EPSG, the implementer may consider using the corresponding metadata values in the EPSG tables.
060 *
061 * @author  OGC Topic 2 (for abstract model and documentation)
062 * @author  Martin Desruisseaux (IRD, Geomatys)
063 * @version 3.1
064 * @since   2.0
065 */
066@Classifier(Stereotype.ABSTRACT)
067@UML(identifier="IdentifiedObject", specification=ISO_19111)
068public interface IdentifiedObject {
069    /**
070     * Key for the <code>{@value}</code> property to be given to the
071     * {@code ObjectFactory.createFoo(Map, ...)} methods.
072     * This is used for setting the value to be returned by {@link #getName()}.
073     *
074     * @see ObjectFactory
075     * @see #getName()
076     */
077    String NAME_KEY = "name";
078
079    /**
080     * Key for the <code>{@value}</code> property to be given to the
081     * {@code ObjectFactory.createFoo(Map, ...)} methods.
082     * This is used for setting the value to be returned by {@link #getAlias()}.
083     *
084     * @see ObjectFactory
085     * @see #getAlias()
086     */
087    String ALIAS_KEY = "alias";
088
089    /**
090     * Key for the <code>{@value}</code> property to be given to the
091     * {@code ObjectFactory.createFoo(Map, ...)} methods.
092     * This is used for setting the value to be returned by {@link #getIdentifiers()}.
093     *
094     * @see ObjectFactory
095     * @see #getIdentifiers()
096     */
097    String IDENTIFIERS_KEY = "identifiers";
098
099    /**
100     * Key for the <code>{@value}</code> property to be given to the
101     * {@code ObjectFactory.createFoo(Map, ...)} methods.
102     * This is used for setting the value to be returned by {@link #getDomains()}.
103     *
104     * @see ObjectFactory
105     * @see #getDomains()
106     *
107     * @since 3.1
108     */
109    String DOMAINS_KEY = "domains";
110
111    /**
112     * Key for the <code>{@value}</code> property to be given to the
113     * {@code ObjectFactory.createFoo(Map, ...)} methods.
114     * This is used for setting the value to be returned by {@link #getRemarks()}.
115     *
116     * @see ObjectFactory
117     * @see #getRemarks()
118     */
119    String REMARKS_KEY = "remarks";
120
121    /**
122     * Returns the primary name by which this object is identified.
123     *
124     * <div class="warning"><b>Upcoming API change — generalization</b><br>
125     * As of ISO 19115:2014, {@code ReferenceIdentifier} has been merged with its {@link Identifier} parent interface.
126     * Consequently this method return type will be changed to {@code Identifier} in GeoAPI 4.0.
127     * </div>
128     *
129     * @return the primary name.
130     */
131    @UML(identifier="name", obligation=MANDATORY, specification=ISO_19111)
132    ReferenceIdentifier getName();
133
134    /**
135     * Returns alternative names by which this object is identified.
136     *
137     * @return alternative names and abbreviations, or an empty collection if there is none.
138     */
139    @UML(identifier="alias", obligation=OPTIONAL, specification=ISO_19111)
140    default Collection<GenericName> getAlias() {
141        return Collections.emptyList();
142    }
143
144    /**
145     * Returns an identifier which references elsewhere the object's defining information.
146     * Alternatively, an identifier by which this object can be referenced.
147     *
148     * <div class="warning"><b>Upcoming API change — generalization</b><br>
149     * As of ISO 19115:2014, {@code ReferenceIdentifier} has been merged with its {@link Identifier} parent interface.
150     * Consequently the element type will be changed to {@code Identifier} in GeoAPI 4.0.
151     * </div>
152     *
153     * @return this object identifiers, or an empty collection if there is none.
154     */
155    @UML(identifier="identifier", obligation=OPTIONAL, specification=ISO_19111)
156    default Set<ReferenceIdentifier> getIdentifiers() {
157        return Collections.emptySet();
158    }
159
160    /**
161     * Returns the usage of this <abbr>CRS</abbr>-related object.
162     * The domain includes a scope (description of the primary purpose of this object) together
163     * with a domain of validity (spatial and temporal extent in which the object can be used).
164     * Those properties are paired together for facilitating descriptions of usage such as
165     * "Purpose 1 in area A, purpose 2 in area B".
166     *
167     * @return scopes and domains of validity of this object.
168     *
169     * @departure generalization
170     *   ISO 19111 defines this property in an {@code ObjectUsage} subtype so that only the
171     *   {@link org.opengis.referencing.datum.Datum},
172     *   {@link org.opengis.referencing.crs.CoordinateReferenceSystem} and
173     *   {@link org.opengis.referencing.operation.CoordinateOperation} subtypes inherit this property.
174     *   GeoAPI relaxes this restriction for two reasons:
175     *   <ul>
176     *     <li>A need to specify a scope can also occur in other subtypes.
177     *         For example a Minkowski {@link org.opengis.referencing.cs.CoordinateSystem}
178     *         may want to specify "For objects moving at relativistic speed" scope.</li>
179     *     <li>The {@code ObjectUsage} type name is at odd with
180     *         the semantics of subclassing as an “is type of” hierarchy.
181     *         Qualifying a CRS as “a type of object usage” is restrictive.
182     *         Instead, CRS <em>contains</em> a description of object usage.
183     *         Omitting the {@code ObjectUsage} subtype avoids this semantic oddity.</li>
184     *   </ul>
185     *
186     * @since 3.1
187     */
188    @UML(identifier="ObjectUsage.domain", obligation=OPTIONAL, specification=ISO_19111)
189    default Collection<ObjectDomain> getDomains() {
190        return Collections.emptyList();
191    }
192
193    /**
194     * Returns comments on or information about this object, including data source information.
195     *
196     * <div class="warning"><b>Upcoming API change — integration</b><br>
197     * The return type will become {@code Optional<InternationalString>} in GeoAPI 4
198     * for consistency with other optional properties in the referencing packages.
199     * </div>
200     *
201     * @return the remarks, or {@code null} if none.
202     */
203    @UML(identifier="remarks", obligation=OPTIONAL, specification=ISO_19111)
204    default InternationalString getRemarks() {
205        return null;
206    }
207
208    /**
209     * Formats a <i>Well-Known Text</i> (WKT) for this object.
210     * Well-Known Texts (WKT) may come in two formats:
211     *
212     * <ul>
213     *   <li>The current standard, WKT 2, is defined by {@linkplain org.opengis.annotation.Specification#ISO_19162 ISO 19162}.</li>
214     *   <li>The legacy format, WKT 1, was defined by {@linkplain org.opengis.annotation.Specification#OGC_01009 OGC 01-009}.</li>
215     * </ul>
216     *
217     * Implementations are encouraged to format according the most recent standard.
218     * This operation may fail if unsupported or if this instance contains elements that do not have
219     * WKT representation.
220     *
221     * @return the Well-Known Text (WKT) for this object.
222     * @throws UnsupportedOperationException if this object cannot be formatted as WKT.
223     *
224     * @departure extension
225     *   This method is not part of the OGC specification. It has been added in order to provide the
226     *   converse of the {@code CRSFactory.createFromWKT(String)} method, which is defined in OGC 01-009.
227     *
228     * @see org.opengis.referencing.crs.CRSFactory#createFromWKT(String)
229     */
230    default String toWKT() throws UnsupportedOperationException {
231        throw new UnsupportedOperationException();
232    }
233}