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.Optional;
022import org.opengis.metadata.citation.Citation;
023import org.opengis.util.Factory;
024import org.opengis.util.FactoryException;
025import org.opengis.util.InternationalString;
026import org.opengis.util.UnimplementedServiceException;
027import org.opengis.annotation.UML;
028
029import static org.opengis.annotation.Obligation.*;
030import static org.opengis.annotation.Specification.*;
031
032
033/**
034 * Base interface for all authority factories.
035 * An <dfn>authority</dfn> is an organization that maintains definitions of authority codes.
036 * An <dfn>authority code</dfn> is a compact string defined by an authority to reference a particular referencing object.
037 *
038 * <p>For example, the <a href="https://epsg.org">EPSG geodetic registry</a> is a database of coordinate
039 * reference systems, and other spatial referencing objects, where each object has a code number ID.
040 * For example, the EPSG code for a <q>WGS84 Lat/Lon</q> <abbr>CRS</abbr> is <q>4326</q>.</p>
041 *
042 * @author  OGC 01-009 (for abstract model and documentation)
043 * @author  Martin Desruisseaux (IRD, Geomatys)
044 * @version 3.1
045 * @since   1.0
046 */
047@UML(identifier="CS_CoordinateSystemAuthorityFactory", specification=OGC_01009)
048public interface AuthorityFactory extends Factory {
049    /**
050     * Returns the organization or party responsible for definition and maintenance of the database.
051     *
052     * @return the organization responsible for definition of the database.
053     */
054    @UML(identifier="getAuthority", specification=OGC_01009)
055    Citation getAuthority();
056
057    /**
058     * Returns the set of authority codes for objects of the given type.
059     * The {@code type} argument specifies the base type of identified objects.
060     *
061     * <h4>Example</h4>
062     * Assuming that this factory is an instance of {@link org.opengis.referencing.crs.CRSAuthorityFactory},
063     * if the {@code type} argument value is set to
064     * <code>{@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem}.class</code>,
065     * then this method should return all authority codes accepted by methods such as
066     * {@link org.opengis.referencing.crs.CRSAuthorityFactory#createGeographicCRS createGeographicCRS(…)},
067     * {@link org.opengis.referencing.crs.CRSAuthorityFactory#createProjectedCRS createProjectedCRS(…)},
068     * {@link org.opengis.referencing.crs.CRSAuthorityFactory#createVerticalCRS createVerticalCRS(…)},
069     * {@link org.opengis.referencing.crs.CRSAuthorityFactory#createTemporalCRS createTemporalCRS(…)}
070     * and any other method returning a sub-type of {@code CoordinateReferenceSystem}.
071     * By contrast, if the {@code type} argument value is set to
072     * <code>{@linkplain org.opengis.referencing.crs.ProjectedCRS}.class</code>,
073     * then this method should return only the authority codes accepted by
074     * {@link org.opengis.referencing.crs.CRSAuthorityFactory#createProjectedCRS createProjectedCRS(…)}.
075     *
076     * @param  type  the type of referencing object for which to get authority codes.
077     * @return the set of authority codes for referencing objects of the given type.
078     * @throws FactoryException if access to the underlying database failed.
079     *
080     * @departure extension
081     *   This method is not part of the OGC specification but has been added as a way to publish
082     *   the capabilities of a factory.
083     */
084    Set<String> getAuthorityCodes(Class<? extends IdentifiedObject> type) throws FactoryException;
085
086    /**
087     * Returns a description of the object corresponding to a code.
088     * The description may be used in graphical user interfaces.
089     * It may be empty if the object corresponding to the specified code has no description.
090     *
091     * @param  type  the type of object for which to get a description.
092     * @param  code  value allocated by the authority for an object of the given type.
093     * @return a description of the object, or empty if the object has no description.
094     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
095     * @throws FactoryException if the query failed for some other reason.
096     *
097     * @since 3.1
098     */
099    @UML(identifier="descriptionText", obligation=OPTIONAL, specification=OGC_01009)
100    default Optional<InternationalString> getDescriptionText(Class<? extends IdentifiedObject> type, String code)
101            throws FactoryException
102    {
103        return Optional.empty();
104    }
105
106    /**
107     * Returns a description of the object corresponding to a code.
108     *
109     * @param  code  value allocated by authority.
110     * @return a description of the object, or {@code null} if the object
111     *         corresponding to the specified {@code code} has no description.
112     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
113     * @throws FactoryException if the query failed for some other reason.
114     *
115     * @deprecated This method is ambiguous because the EPSG geodetic registry may allocate
116     *             the same code to different kinds of object.
117     */
118    @Deprecated(since="3.1", forRemoval=true)
119    default InternationalString getDescriptionText(String code) throws FactoryException {
120        return getDescriptionText(IdentifiedObject.class, code).orElse(null);
121    }
122
123    /**
124     * Returns an arbitrary object from a code. The returned object will typically be an
125     * instance of {@link org.opengis.referencing.datum.Datum}, {@link org.opengis.referencing.cs.CoordinateSystem},
126     * {@link org.opengis.referencing.ReferenceSystem} or {@link org.opengis.referencing.operation.CoordinateOperation}.
127     *
128     * <p>If the object type is known at compile time, then it is recommended to invoke the
129     * most precise method instead of this one. For example, it is usually better to invoke
130     * <code>{@linkplain org.opengis.referencing.crs.CRSAuthorityFactory#createCoordinateReferenceSystem
131     * createCoordinateReferenceSystem}(code)</code> instead of {@code createObject(code)}
132     * if the requested object is known to be a {@code CoordinateReferenceSystem} instance.</p>
133     *
134     * @param  code  value allocated by authority.
135     * @return the object for the given code.
136     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
137     * @throws FactoryException if the object creation failed for some other reason.
138     *
139     * @departure generalization
140     *   This method is not part of the OGC specification. It has been added to leverage the
141     *   capability of factories that can automatically determine the type of the requested
142     *   object at runtime.
143     *
144     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createDatum(String)
145     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createCoordinateReferenceSystem(String)
146     *
147     * @deprecated This method is ambiguous because the EPSG geodetic registry may allocate the same code
148     *             to different kinds of object. A more specialized method such as {@code createDatum(…)},
149     *             {@code createCoordinateSystem(…)} or {@code createCoordinateReferenceSystem(…)} should
150     *             be invoked instead.
151     */
152    @Deprecated(since="3.1", forRemoval=true)
153    default IdentifiedObject createObject(String code) throws FactoryException {
154        throw new UnimplementedServiceException(this, IdentifiedObject.class);
155    }
156}