001/*
002 *    GeoAPI - Java interfaces for OGC/ISO standards
003 *    Copyright © 2004-2023 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 org.opengis.referencing.AuthorityFactory;
021import org.opengis.referencing.NoSuchAuthorityCodeException;
022import org.opengis.util.UnimplementedServiceException;
023import org.opengis.util.FactoryException;
024import org.opengis.annotation.UML;
025
026import static org.opengis.annotation.Specification.*;
027import static org.opengis.geoapi.internal.Errors.unexpectedType;
028
029
030/**
031 * Creates datum objects using authority codes.
032 * External authorities are used to manage definitions of objects used in this interface.
033 * The definitions of these objects are referenced using code strings.
034 * A commonly used authority is the <a href="https://epsg.org">EPSG geodetic registry</a>.
035 *
036 * <h2>Default methods</h2>
037 * All {@code create(…)} methods in this interface are optional.
038 * If a method is not overridden by the implementer, the default is:
039 * <ul>
040 *   <li>For methods creating a sub-type of {@link Datum}, delegate to
041 *       {@link #createDatum(String)} then check the returned object type.</li>
042 *   <li>For all other methods, throw an {@link UnimplementedServiceException} with a message
043 *       saying that the type or service is not supported.</li>
044 * </ul>
045 *
046 * @author  OGC 01-009 (for abstract model and documentation)
047 * @author  Martin Desruisseaux (IRD, Geomatys)
048 * @author  Johann Sorel (Geomatys)
049 * @version 3.1
050 * @since   1.0
051 *
052 * @see org.opengis.referencing.cs.CSAuthorityFactory
053 * @see org.opengis.referencing.crs.CRSAuthorityFactory
054 */
055@UML(identifier="CS_CoordinateSystemAuthorityFactory", specification=OGC_01009)
056public interface DatumAuthorityFactory extends AuthorityFactory {
057    /**
058     * Returns an ellipsoid from a code.
059     *
060     * @param  code  value allocated by authority.
061     * @return the ellipsoid for the given code.
062     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
063     * @throws FactoryException if the object creation failed for some other reason.
064     *
065     * @see #createGeodeticDatum(String)
066     */
067    @UML(identifier="createEllipsoid", specification=OGC_01009)
068    default Ellipsoid createEllipsoid(String code) throws FactoryException {
069        throw new UnimplementedServiceException(this, Ellipsoid.class);
070    }
071
072    /**
073     * Returns a prime meridian from a code.
074     *
075     * @param  code  value allocated by authority.
076     * @return the prime meridian for the given code.
077     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
078     * @throws FactoryException if the object creation failed for some other reason.
079     *
080     * @see #createGeodeticDatum(String)
081     */
082    @UML(identifier="createPrimeMeridian", specification=OGC_01009)
083    default PrimeMeridian createPrimeMeridian(String code) throws FactoryException {
084        throw new UnimplementedServiceException(this, PrimeMeridian.class);
085    }
086
087    /**
088     * Returns an arbitrary datum from a code.
089     *
090     * <p>If the datum type is known at compile time, then it is recommended to invoke the
091     * most precise method instead of this one. For example, it is usually better to invoke
092     * <code>{@linkplain #createGeodeticDatum createGeodeticDatum}(code)</code> instead of
093     * {@code createDatum(code)} if the requested object is known to be a
094     * {@code GeodeticDatum} instance.</p>
095     *
096     * @param  code  value allocated by authority.
097     * @return the datum for the given code.
098     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
099     * @throws FactoryException if the object creation failed for some other reason.
100     *
101     * @see #createGeodeticDatum(String)
102     * @see #createVerticalDatum(String)
103     * @see #createTemporalDatum(String)
104     */
105    default Datum createDatum(String code) throws FactoryException {
106        throw new UnimplementedServiceException(this, Datum.class);
107    }
108
109    /**
110     * Returns a geodetic reference frame from a code.
111     *
112     * @param  code  value allocated by authority.
113     * @return the datum for the given code.
114     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
115     * @throws FactoryException if the object creation failed for some other reason.
116     *
117     * @see #createEllipsoid(String)
118     * @see #createPrimeMeridian(String)
119     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createGeographicCRS(String)
120     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createProjectedCRS(String)
121     */
122    @UML(identifier="createHorizontalDatum", specification=OGC_01009)
123    default GeodeticDatum createGeodeticDatum(final String code) throws FactoryException {
124        final Datum datum = createDatum(code);
125        try {
126            return (GeodeticDatum) datum;
127        } catch (ClassCastException e) {
128            throw unexpectedType(this, code, datum, e);
129        }
130    }
131
132    /**
133     * Returns a vertical datum from a code.
134     *
135     * @param  code  value allocated by authority.
136     * @return the datum for the given code.
137     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
138     * @throws FactoryException if the object creation failed for some other reason.
139     *
140     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createVerticalCRS(String)
141     */
142    @UML(identifier="createVerticalDatum", specification=OGC_01009)
143    default VerticalDatum createVerticalDatum(final String code) throws FactoryException {
144        final Datum datum = createDatum(code);
145        try {
146            return (VerticalDatum) datum;
147        } catch (ClassCastException e) {
148            throw unexpectedType(this, code, datum, e);
149        }
150    }
151
152    /**
153     * Returns a temporal datum from a code.
154     *
155     * @param  code  value allocated by authority.
156     * @return the datum for the given code.
157     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
158     * @throws FactoryException if the object creation failed for some other reason.
159     *
160     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createTemporalCRS(String)
161     */
162    default TemporalDatum createTemporalDatum(final String code) throws FactoryException {
163        final Datum datum = createDatum(code);
164        try {
165            return (TemporalDatum) datum;
166        } catch (ClassCastException e) {
167            throw unexpectedType(this, code, datum, e);
168        }
169    }
170
171    /**
172     * Returns a parametric datum from a code.
173     *
174     * @param  code  value allocated by authority.
175     * @return the datum for the given code.
176     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
177     * @throws FactoryException if the object creation failed for some other reason.
178     *
179     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createParametricCRS(String)
180     */
181    default ParametricDatum createParametricDatum(final String code) throws FactoryException {
182        final Datum datum = createDatum(code);
183        try {
184            return (ParametricDatum) datum;
185        } catch (ClassCastException e) {
186            throw unexpectedType(this, code, datum, e);
187        }
188    }
189
190    /**
191     * Returns a engineering datum from a code.
192     *
193     * @param  code  value allocated by authority.
194     * @return the datum for the given code.
195     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
196     * @throws FactoryException if the object creation failed for some other reason.
197     *
198     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createEngineeringCRS(String)
199     */
200    default EngineeringDatum createEngineeringDatum(final String code) throws FactoryException {
201        final Datum datum = createDatum(code);
202        try {
203            return (EngineeringDatum) datum;
204        } catch (ClassCastException e) {
205            throw unexpectedType(this, code, datum, e);
206        }
207    }
208
209    /**
210     * Returns a image datum from a code.
211     *
212     * @param  code  value allocated by authority.
213     * @return the datum for the given code.
214     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
215     * @throws FactoryException if the object creation failed for some other reason.
216     *
217     * @see org.opengis.referencing.crs.CRSAuthorityFactory#createImageCRS(String)
218     *
219     * @deprecated {@code ImageDatum} is replaced by {@link EngineeringDatum} as of ISO 19111:2019.
220     */
221    @Deprecated(since="3.1")
222    default ImageDatum createImageDatum(final String code) throws FactoryException {
223        final Datum datum = createDatum(code);
224        try {
225            return (ImageDatum) datum;
226        } catch (ClassCastException e) {
227            throw unexpectedType(this, code, datum, e);
228        }
229    }
230
231    /**
232     * Returns an arbitrary object from a code.
233     *
234     * @param  code  value allocated by authority.
235     * @return the object for the given code.
236     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
237     * @throws FactoryException if the object creation failed for some other reason.
238     *
239     * @deprecated This method is ambiguous. Use {@link #createDatum(String)} instead.
240     */
241    @Override
242    @SuppressWarnings("removal")
243    @Deprecated(since="3.1", forRemoval=true)
244    default org.opengis.referencing.IdentifiedObject createObject(String code) throws FactoryException {
245        return createDatum(code);
246    }
247}